Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Finally' Block in Iterators

Tags:

iterator

c#

Is there any way in a C# iterator block to provide a block of code which will be run when the foreach ends (either naturally of by being broken out of), say to clean up resources?

The best I have come up with is to use the using construct, which is fine but does need an IDisposable class to do the clean up. For example:

    public static IEnumerable<string> ReadLines(this Stream stream)
    {
        using (StreamReader rdr = new StreamReader(stream))
        {
            string txt = rdr.ReadLine();
            while (txt != null)
            {
                yield return txt;
                txt = rdr.ReadLine();
            }
            rdr.Close();
        }
    }
like image 725
JDunkerley Avatar asked Oct 02 '09 07:10

JDunkerley


1 Answers

try/finally works fine, so long as the caller is using a foreach or manually calls Dispose on the IEnumerator<T>. To be honest, if it's to clean up resources, a using statement is probably going to be the best way of doing it anyway - if you're using a resource which needs cleaning up but doesn't implement IDisposable, that's a concern in itself :)

There are certain restrictions on what you can do in iterator blocks, as explained on Eric Lippert's blog, but it all works very nicely in most cases.

You may find my article about iterator block implementation interesting in terms of how finally is translated.

like image 199
Jon Skeet Avatar answered Nov 05 '22 13:11

Jon Skeet