Reputation: 5660
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?
Upvotes: 44
Views: 17442
Reputation: 17038
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
.
Upvotes: 41
Reputation: 6175
Here's a cleaner syntax:
foreach (ManagementObject obj in result) using (obj)
{
// do your stuff here
}
Upvotes: 7
Reputation: 456887
ManagementObjectCollection
is itself IDisposable
...
So it would be...
using (var results = ..)
{
foreach (var result in results)
{
using (result)
{
...
}
}
}
Upvotes: 4
Reputation: 13075
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.
Upvotes: 4
Reputation: 48959
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();
}
}
Upvotes: 24
Reputation: 16178
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.
Upvotes: -1