我遍歷一個ManageObjectCollection(它是WMI接口的一部分)。結合使用foreach和使用
但重要的是,下面這行代碼。 :
foreach (ManagementObject result in results)
{
//code here
}
問題是ManageObject也實現了IDisposable,所以我想把「result」變量放在一個using塊中。有關如何做到這一點的想法,不要太奇怪或複雜?
我遍歷一個ManageObjectCollection(它是WMI接口的一部分)。結合使用foreach和使用
但重要的是,下面這行代碼。 :
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
。 foreach
將在枚舉器上調用Dispose()
。
它看起來很奇怪 - 遍歷數組並處理它包含的每個對象。如果你真的想這樣做,使用
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
聲明一樣。
因爲這是「正是使用聲明所做的」,所以你不應該這樣做。 – CertifiedCrazy 2018-01-09 17:14:55
ManagementObjectCollection
本身IDisposable
...
因此,這將是...
using (var results = ..)
{
foreach (var result in results)
{
using (result)
{
...
}
}
}
這不會在每個'ManagementObject'上調用Dispose(),只會在'ManagementObjectCollection'本身上調用Dispose()。 – 2010-06-09 11:35:15
爲了非常無聊,它會在'foreach'循環中的'ManagementObjectCollection'和'IEnumerator'上調用'Dispose'。 – 2010-06-09 13:02:27
你可以做到以下幾點。
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();
}
}
你可以通過擴展方法和枚舉器得到一個很好的整齊語法。首先,在你的代碼在某處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'對類型約束進行泛化。 – Chad 2013-04-11 19:09:56
你可以,但這絕對是一個特例。通常處理一次性物品的集合也應該處理其包含的物品。 (爲了這個目的,我在代碼中定義了一個通用的'DisposableList')。 – Miral 2013-04-12 02:44:07
還有一個警告 - 如果你真的完全遍歷返回的枚舉,它將只處理所有事情。如果你在中途停下,那麼這個藏品仍然會被丟棄,但是你還沒有看過的任何物品都不會。當然,這也適用於這裏發佈的大多數其他答案。 – Miral 2013-06-05 07:20:45
這裏有一個更清晰的語法:
foreach (ManagementObject obj in result) using (obj)
{
// do your stuff here
}
我覺得Dispose方法已經在那裏建立 – Arseny 2010-06-09 11:24:42
無,處置任何地方都可以稱爲一個網站,「結果」的對象被調用。 – 2010-06-09 11:47:00
foreach自動調用Disume Enumerable,如果它是IDisposable,那麼首先使用不必要的 – Alexander 2013-06-06 05:28:27