Question Combiner foreach et utiliser


Je suis itéré sur un ManageObjectCollection. (Qui fait partie de l'interface WMI).

Cependant, la chose importante est la ligne de code suivante. :

foreach (ManagementObject result in results)
{
    //code here
}

Le fait est que ManageObject implémente également IDisposable, donc je voudrais mettre la variable "result" dans un bloc using. Une idée sur comment faire cela sans devenir trop bizarre ou complexe?


24
2018-06-09 11:17


origine


Réponses:


foreach (ManagementObject result in results)
using(result)
{
    //code here
}

Ce n’est normalement pas une bonne pratique d’affecter la variable en dehors du using bloquer car la ressource serait éliminée mais pourrait rester dans la portée. Il en résulterait cependant un code plus clair car vous pouvez imbriquer le using déclaration contre le foreach.

MODIFIER: Comme indiqué dans une autre réponse, ManagementObjectCollection met également en œuvre IDisposable donc j'ai ajouté cela dans un using bloc.

Pas besoin de placer ManagementObjectCollection dans une déclaration d'utilisation. la foreach appellera Dispose() sur le recenseur.


24
2018-06-09 11:22



Vous pourriez faire ce qui suit.

foreach (ManagementObject result in results)
{
  using (result)
  {
    // Your code goes here.
  }
}

La chose intéressante à propos de C # est la façon dont différentes constructions de langage peuvent partager des blocs de code de portée. Cela signifie que vous pouvez faire ce qui suit pour éliminer l’imbrication.

foreach (ManagementObject result in results) using (result)
{
  // Your code goes here.
}

Il est également utile de savoir que le foreach construire appellera Dispose sur la cible IEnumerator ainsi que. Le code ci-dessus serait équivalent à.

IEnumerator enumerator = results.GetEnumerator()
try
{
  while (enumerator.MoveNext())
  {
    ManagementObject result = (ManagementObject)enumerator.Current;
    IDisposable disposable = (IDisposable)result;
    try
    {
      // Your code goes here.
    }
    finally
    {
      disposable.Dispose();
    }
  }
}
finally
{
  IDisposable disposable = enumerator as IDisposable;
  if (disposable != null)
  {
    disposable.Dispose();
  }
}

13
2018-06-09 12:55



Vous pouvez obtenir une syntaxe soignée grâce aux méthodes d'extension et aux énumérateurs. Tout d'abord, définissez cela dans un public static class quelque part dans votre code:

public static IEnumerable<ManagementObject> WithDisposal(
                    this ManagementObjectCollection list)
{
    using (list)
    {
        foreach (var obj in list)
        {
            using (obj)
            {
                yield return obj;
            }
        }
    }
 }

... que vous pouvez ensuite utiliser avec juste ceci:

foreach (var obj in /*get the results*/.WithDisposal())
{
    // ...
}

Bien que gardez à l'esprit que si vous utilisez WithDisposal Vous ne pourrez alors enregistrer aucun objet pour une utilisation ultérieure.


3
2018-04-06 07:49



ManagementObjectCollection est lui-même IDisposable...

Donc ce serait ...

using (var results = ..)
{
    foreach (var result in results)
    {
        using (result)
        {
            ...
        }
    }
}

2
2018-06-09 11:33



Voici une syntaxe plus propre:

foreach (ManagementObject obj in result) using (obj)
{
  // do your stuff here
}

1
2018-06-25 09:48



Cela aura l'air étrange - itérer sur le tableau et disposer de chacun des objets qu'il contient. Si vous voulez vraiment faire cela, utilisez

foreach (ManagementObject result in results)
{
    try {
        // code here
    }
    finally {
        result.Dispose();
    }
}

/* do not forget to, or to not reuse results!
results = null; 
results.Clear();
*/

qui est exactement ce que using déclaration fait.


-1
2018-06-09 11:22