结合foreach和使用

时间:2010-06-09 11:17:24

标签: c# foreach idisposable using

我正在迭代一个ManageObjectCollection。(它是WMI接口的一部分)。

然而重要的是,以下代码行。 :

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

关键是ManageObject也实现了IDisposable,所以我想把“result”变量放在using块中。关于如何做到这一点的任何想法,而不是太奇怪或复杂?

6 个答案:

答案 0 :(得分:24)

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

将变量分配到using块之外通常不是一种好的做法,因为资源将被处理但可以保留在范围内。但是,这会导致代码更清晰,因为您可以将using语句嵌套到foreach

编辑: 正如另一个答案所指出的那样,ManagementObjectCollection也实现了IDisposable所以我已将其添加到using块中。

无需将ManagementObjectCollection放在using语句中。 foreach将在枚举器上调用Dispose()

答案 1 :(得分:16)

您可以执行以下操作。

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

关于C#的巧妙之处在于不同的语言结构如何共享作用域代码块。这意味着您可以执行以下操作来消除嵌套。

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

答案 2 :(得分:4)

您可以通过扩展方法和枚举器获得一个很好的语法。首先,在代码中的某个地方的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,那么您将无法保存任何对象以供将来使用。

答案 3 :(得分:2)

ManagementObjectCollection本身就是IDisposable ...

所以它会......

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

答案 4 :(得分:1)

这是一个更清晰的语法:

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

答案 5 :(得分:-1)

看起来很奇怪 - 迭代数组并处理它包含的每个对象。如果您真的想这样做,请使用

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语句的作用。