3

I came across the following example code in the MSDN documentation, demonstrating the use of the System.IO.StreamReader class to read UTF-8 text from a System.IO.FileStream object. The two nested using statements struck me as redundant - surely calling Dispose() on one of the objects does the trick, and properly releases the file handle? (Source: http://msdn.microsoft.com/en-us/library/yhfzs7at.aspx)

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

        while (sr.Peek() >= 0) 
        {
            Console.WriteLine(sr.ReadLine());
        }
    }
}

Would it not be simpler, and equally correct, to rewrite that code in the following way?

using (FileStream fs = new FileStream(path, FileMode.Open)) 
{
    StreamReader sr = new StreamReader(fs);

    while (sr.Peek() >= 0) 
    {
        Console.WriteLine(sr.ReadLine());
    }
}
2
  • 1
    I believe it's a good idea to dispose all that implements IDisposable. Commented Sep 13, 2014 at 19:57
  • Similar question with good answers: stackoverflow.com/q/9949377/361684 Commented Sep 13, 2014 at 20:18

2 Answers 2

3

According to the documentation, The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called. This means using the StreamReader guarantees disposal of the underlying Stream. It does not hold vice versa: disposing only the Stream does not suffice - the StreamReader may be allocating other native resources. So the second sample is not correct.

(using only the StreamReader does not cover the case that the StreamReader constructor can throw. To cover this case, both using's would be needed. Since it only throws for non-readable or null streams, this may not be relevant though.)

In general, you should always dispose on every disposable object. It is part of the IDisposable contract that it does not hurt to dispose an object multiple times, and the overhead of doing so is low.

Sign up to request clarification or add additional context in comments.

2 Comments

Your quote is correct but does not relate to the 2nd code sample.
@HenkHolterman I am also saying that the second sample is for this very reason not correct.
3

The second sample is simply wrong on principle.

It won't leak anything but that relies on the knowledge that a StreamReader has no resources of its own and does not actually needs Disposing even though it is IDisposable.

A single using(){} around the StreamReader would have been more or less correct here, based on the documented (and criticized) feature that the Reader will close its Stream.

The best practice here is to use 2 using statments. Note that they are very cheap, and you simply want code that's consistent.

4 Comments

Note that StreamReader also provides an option to say don't close the underlying stream. Also single using statement only in StreamReader is a problem when its constructor throws, FileStream will not be closed.
@SriramSakthivel - as of Fx 4.5, yes. But that is not the cotor being used here.
True, I'm adding to say there is an option to leave the stream open. Btw I edited my previous comment to point that single using statement around StreamReader will be dangerous.
That argument about throwing is very generic and does not apply to this code fragment. I wouldn't encourage the single using but not fault it either in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.