tags:

views:

101

answers:

4
foreach(var someDisposableObject in listOfDisposableObjects)
{
    //some code
    someDisposableObject.Dispose(); //current code contains something like this.
}

Is there safe way, like a using clause to use in this scenario?

For my second iteration (before getting responses) I changed the code to

foreach(var someDisposableObject in listOfDisposableObjects)
{
    try
    {
        //some code
    }
    finally
    {
        someDisposableObject.Dispose(); //current code contains something like this.
    }
}

though

foreach(var someDisposableObject in listOfDisposableObjects)
{
    using( someDisposableObject )
    {
        //some code
    }
}

is much more tidy and most likely safer.

+2  A: 
    foreach(var someDisposableObject in listOfDisposableObjects)
    {
        using (someDisposableObject)
        {
           //some code
        }
    }
Andrey
If `//some code` throws an error, then any disposable objects in the list after the current one will not be disposed. This code only differs from the OP in that the object currently being processed will be disposed.
Jeffrey L Whitledge
I just didn't know that was valid/legit/possible. Simple. Thanks.
Greg Ogle
I agree with Jeffrey. This answer is seriously flawed and should not be the accepted answer.
David Walschots
A: 

See http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

As far as I can gather, you should call Dispose(true)

rep_movsd
No, `Dispose(bool)` would be the `protected virtual` method used as an extensibility point for the dispose implementation. The caller would call the `Dispose()` method which would call it. In any case, this doesn't even remotely answer the question...
Greg Beech
+1  A: 

I think this may be your best bet:

try
{
    foreach(var someDisposableObject in listOfDisposableObjects) 
    { 
        //some code 
    } 
}
finally
{
    foreach(var someDisposableObject in listOfDisposableObjects) 
    { 
        someDisposableObject.Dispose();
    } 
}

EDITED TO ADD:

If you absolutely have to dispose of every object no matter what, then you can do this:

    private static void DoStuff(IEnumerable<IDisposable> listOfDisposableObjects)
    {
        using (var enumerator = listOfDisposableObjects.GetEnumerator())
        {
            if (enumerator.MoveNext())
                DoStuffCore(enumerator);
        }
    }

    private static void DoStuffCore(IEnumerator<IDisposable> enumerator)
    {
        using (var someDisposableObject = enumerator.Current)
        {
            if (enumerator.MoveNext())
                DoStuffCore(enumerator);

            // Do stuff with someDisposableObject                
        }
    }
Jeffrey L Whitledge
This could fail in the finally block.
Greg Ogle
Sure it could. If you're concerned that the Dispose method itself could throw, then you'll have to do something else.
Jeffrey L Whitledge
@Greg Ogle - OK, I added a solution that will *always* dispose of the objects. (Unless there's a catastrophic error, of course. I can't stop a power failure!)
Jeffrey L Whitledge
+1 Great trick.
SLaks
+3  A: 

I would say your Dispose code should be outside of this foreach.

The key point you haven't addressed in your sample is how the list of disposable objects is generated. What happens if an exception is thrown while you are generating the list of disposable objects? You will want to dispose those that you have created so far.

Ideally you want a container that implements IDisposable to hold your disposable objects. If your disposable objects implement IComponent, then System.ComponentModel.Container is what you need. If not, you may have to roll your own.

Code might look something like:

using(Container container = new Container())
{
    // Generate list and add each element to the container
    for (...)
    {
        someDisposableComponent = ...;
        container.Add(someDisposableComponent);
        listOfDisposableObjects.Add(someDisposableComponent);
    }

    ... 

    foreach(var someDisposableObject in listOfDisposableObjects)
    {
        ... some code ...
    }
}

I suggest you post code that generates the list if you need more help.

Joe