Search code examples
c#.netidisposableusing-statementtry-finally

Returning from method disposes corectly the object?


If you use the using method instead of lets say FileStream.Close();, will the class dispose correctly?

private static string GetString()
{
    using(FileStream fs = new FileStream("path", FileMode.Open))
    using(StreamReader sr = new StreamReader(fs))
    {
         return sr.ReadToEnd();
    }
}

is equivalent to:

private static string GetString()
{
    string toReturn = "";           

    FileStream fs = new FileStream("path", FileMode.Open)
    StreamReader sr = new StreamReader(fs)

    toReturn = sr.ReadToEnd();

    sr.Close();
    fs.Close();

    return toReturn;
}

or to:

private static string GetString()
{
    FileStream fs;
    StreamReader sr;

    try
    {
        string toReturn = "";          

        fs = new FileStream("path", FileMode.Open)
        sr = new StreamReader(fs)

        toReturn = sr.ReadToEnd();

        sr.Close();
        fs.Close();

        return toReturn;
    }
    finally
    {
       if(sr != null)
           sr.Close();

       if(fs != null)
           fs.Close();
    }
}

Solution

  • The code generated from a using statement is very similar to your second example (the biggest difference being that it calls IDisposable.Dispose instead of Close). It will always properly dispose of the objects, whether the method exits through a return or a thrown exception.

    In case you're curious, this is the C# code without usings that compiles to the same IL as your example with usings:

    private static string GetString()
    {
        FileStream fs = new FileStream("path", FileMode.Open);
        try
        {
            StreamReader sr = new StreamReader(fs);
            try
            {
                return sr.ReadToEnd();
            }
            finally
            {
                if (sr != null)
                    ((IDisposable)sr).Dispose();
            }
        }
        finally
        {
            if (fs != null)
                ((IDisposable)fs).Dispose();
        }
    }