oglester
oglester

Reputation: 6655

How does one Dispose an object that is set in foreach?

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.

Upvotes: 1

Views: 1245

Answers (3)

Andrey
Andrey

Reputation: 60075

Since there was no mention of the need to dispose of all un-enumerated items. We can handle it safely as below as we don´t leave room for code execution between the foreach and using block.

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

Upvotes: 2

Jeffrey L Whitledge
Jeffrey L Whitledge

Reputation: 59503

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                
        }
    }

Upvotes: 3

to StackOverflow
to StackOverflow

Reputation: 124746

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.

Upvotes: 3

Related Questions