我正在遍历一个ManageObjectCollection。(这是WMI接口的一部分)。
然而,重要的是以下代码行:
foreach (ManagementObject result in results)
{
//code here
}
关键在于ManageObject也实现了IDisposable,因此我想将"result"变量放在using块中。有什么办法能做到这一点,而不会变得太奇怪或太复杂吗?
我正在遍历一个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
循环语句会调用目标 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();
}
}
这里有一个更简洁的语法:
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
,那么您将无法保存任何对象以供将来使用。
IDisposable
施加类型约束来使其通用。 - ChadManagementObjectCollection
本身是IDisposable
接口...
因此,应该...
using (var results = ..)
{
foreach (var result in results)
{
using (result)
{
...
}
}
}
foreach
循环中使用的ManagementObjectCollection
和IEnumerator
上都调用Dispose
方法。 - Brian Gideon这看起来很奇怪 - 迭代数组并处理其中包含的每个对象。如果您真的想这样做,请使用
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
语句所做的。