Объединение foreach и использование
Я выполняю итерацию над ManageObjectCollection (которая является частью интерфейса WMI).
Однако важно то, что следующая строка кода.
foreach (ManagementObject result in results)
{
//code here
}
Дело в том, что ManageObject также реализует IDisposable, поэтому я хотел бы поместить переменную result в блок использования. Любая идея о том, как это сделать, без слишком странного или сложного?
Ответы
Ответ 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
.