结合foreach和使用

apo*_*020 30 c# foreach idisposable using

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

但重要的是,以下代码行.:

foreach (ManagementObject result in results)
{
    //code here
}
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*ale 26

foreach (ManagementObject result in results)
using(result)
{
    //code here
}
Run Code Online (Sandbox Code Playgroud)

using块之外分配变量通常不是好的做法,因为资源将被处理但可以保留在范围内.但是,它会在这里产生更清晰的代码,因为你可以将using语句嵌套在foreach.

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

无需放入ManagementObjectCollection使用声明.在foreach将调用Dispose()的枚举.

  • 如果是 IDisposable,foreach 会在 Enumerable 上自动调用 Dispose,所以首先使用不必要的 (2认同)
  • @Alexander foreach将在Enumerator上调用Dispose,它将由ManagementObjectCollection GetEnumerator()方法返回.不会在ManagementObjectCollection对象上调用Dispose. (2认同)

Bri*_*eon 19

您可以执行以下操作.

foreach (ManagementObject result in results)
{
  using (result)
  {
    // Your code goes here.
  }
}
Run Code Online (Sandbox Code Playgroud)

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

foreach (ManagementObject result in results) using (result)
{
  // Your code goes here.
}
Run Code Online (Sandbox Code Playgroud)

知道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();
  }
}
Run Code Online (Sandbox Code Playgroud)


Uri*_*son 7

这是一个更清晰的语法:

foreach (ManagementObject obj in result) using (obj)
{
  // do your stuff here
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种语法,但 Visual Studio 搞砸了格式(它向块添加了一个额外的选项卡)。 (2认同)