我正在迭代 ManageObjectCollection。(它是 WMI 接口的一部分)。
不过重要的是下面这行代码。 :
foreach (ManagementObject result in results)
{
//code here
}
重点是 ManageObject 还实现了 IDisposable,所以我想将“result”变量放在 using 块中。知道如何做到这一点,而又不会变得太奇怪或复杂吗?
foreach (ManagementObject result in results) using (result)
{
//code here
}
在
using
块之外分配变量通常不是好习惯,因为资源将被释放,但可能保留在范围内。然而,这会导致这里的代码更清晰,因为您可以将 using
语句嵌套在 foreach
上。
编辑:
正如另一个答案中指出的,
ManagementObjectCollection
IDisposable
,所以我将其添加到using
块中。无需将
ManagementObjectCollection
放在 using 语句中。 foreach
将调用枚举器上的 Dispose()
。
您可以执行以下操作。
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();
}
}
这是一个更清晰的语法:
foreach (ManagementObject obj in result) using (obj)
{
// do your stuff here
}
您可以通过扩展方法和枚举器获得简洁的语法。首先,在代码中的某个位置
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
那么您将无法保存任何对象以供将来使用。
ManagementObjectCollection
本身就是IDisposable
...
所以会是...
using (var results = ..)
{
foreach (var result in results)
{
using (result)
{
...
}
}
}
它看起来很奇怪 - 迭代数组并处理它包含的每个对象。如果您确实想这样做,请使用
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
语句的作用。