结合 foreach 和 using

发布于 09-05 02:47 字数 512 浏览 12 评论 0原文

我正在迭代 ManagementObjectCollection (这是WMI 接口的一部分)。

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

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

重点是 ManagementObject 也实现了 IDisposable,所以我想将“结果”变量放在 using 块中。知道如何做到这一点,而又不会变得太奇怪或复杂吗?

I'm iterating over a ManagementObjectCollection ( which is part of the WMI interface).

However, the important thing is, the following line of code. :

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

The point is that ManagementObject also implements IDisposable, so I would like to put the "result" variable in a using block. Any idea on how to do this, without getting too weird or complex?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

小嗷兮2024-09-12 02:47:03
foreach (ManagementObject result in results) using (result)
{
    //code here
}

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

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

Assigning the variable outside the using block is not normally good practice because the resource would be disposed of but could stay in scope. It would, however, result in clearer code here because you can nest the using statement against the foreach.

虫児飞2024-09-12 02:47:03

您可以执行以下操作。

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

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

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

了解 foreach 构造也会在目标 IEnumerator 上调用 Dispose 也很有用。上面的代码相当于。

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

You could do the following.

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

The neat thing about C# is how different language constructs can share scoped code blocks. That means you could do the following to eliminate the nesting.

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

It is also useful to know that the foreach construct will call Dispose on the target IEnumerator as well. The code above would be equivalent to.

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();
  }
}
看轻我的陪伴2024-09-12 02:47:03

这是一个更清晰的语法:

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

Here's a cleaner syntax:

foreach (ManagementObject obj in result) using (obj)
{
  // do your stuff here
}
╰つ倒转2024-09-12 02:47:03

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

You can get a nice neat syntax via extension methods and enumerators. First, define this in a public static class somewhere in your code:

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

... which you can then use with just this:

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

Though bear in mind that if you use WithDisposal then you won't be able to save any of the objects for future use.

毅然前行2024-09-12 02:47:03

ManagementObjectCollection 本身就是 IDisposable...

所以它会是...

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

ManagementObjectCollection is itself IDisposable...

So it would be...

using (var results = ..)
{
    foreach (var result in results)
    {
        using (result)
        {
            ...
        }
    }
}
墨离汐2024-09-12 02:47:03

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

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

It will look weird - iterating over array and disposing each of the objects it contains. If you really want to do this, use

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

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

which is exactly what using statement does.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文