Подтвердить что ты не робот

Объединение foreach и использование

Я выполняю итерацию над ManageObjectCollection (которая является частью интерфейса WMI).

Однако важно то, что следующая строка кода.

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

Дело в том, что ManageObject также реализует IDisposable, поэтому я хотел бы поместить переменную result в блок использования. Любая идея о том, как это сделать, без слишком странного или сложного?

4b9b3361

Ответ 1

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

Обычно не рекомендуется назначать переменную вне блока using, потому что ресурс будет удален, но может оставаться в области видимости. Это, однако, привело бы к более четкому коду здесь, потому что вы можете вставить оператор using в соответствие с foreach.

EDIT: Как указано в другом ответе, ManagementObjectCollection также реализует IDisposable, поэтому я добавил это в блок using.

Не нужно помещать ManagementObjectCollection в оператор using. foreach вызовет Dispose() в перечислителе.

Ответ 2

Вы можете сделать следующее.

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

Оптимальная вещь о С# заключается в том, как различные языковые конструкции могут совместно использовать облачные кодовые блоки. Это означает, что вы можете сделать следующее, чтобы устранить вложенность.

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

Также полезно знать, что конструкция foreach вызовет Dispose на целевом IEnumerator. Вышеприведенный код был бы эквивалентен.

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();
  }
}

Ответ 3

Вы можете получить хороший аккуратный синтаксис с помощью методов расширения и перечислений. Сначала определите это в public static class где-нибудь в вашем коде:

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

... который вы можете использовать только с этим:

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

Хотя помните, что если вы используете WithDisposal, вы не сможете сохранить какой-либо объект для будущего использования.

Ответ 4

ManagementObjectCollection сам IDisposable...

Итак, это было бы...

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

Ответ 5

Здесь более чистый синтаксис:

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

Ответ 6

Это будет выглядеть странно - итерация по массиву и удаление каждого из содержащихся в нем объектов. Если вы действительно хотите это сделать, используйте

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

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

что и делает оператор using.