Does .Disposing a StreamWriter close the underlying stream?

The StreamWriter.Close() says it also closes the underlying stream of the StreamWriter. What about StreamWriter.Dispose ? Does Dispose also dispose and/or close the underlying stream


Solution 1:

StreamWriter.Close() just calls StreamWriter.Dispose() under the bonnet, so they do exactly the same thing. StreamWriter.Dispose() does close the underlying stream.

Reflector is your friend for questions like this :)

Solution 2:

Some people will say, just dont dispose the stream, this is a really bad idea, because once the streamwriter goes out of scope GarbageCollection can pick it up anytime and dipose it, thus closing the Handle to the stream, but creating a descendant class which overrides this behaviour of StreamWriter is easy, heres the code:

/// <summary>
/// Encapsulates a stream writer which does not close the underlying stream.
/// </summary>
public class NoCloseStreamWriter : StreamWriter
{
    /// <summary>
    /// Creates a new stream writer object.
    /// </summary>
    /// <param name="stream">The underlying stream to write to.</param>
    /// <param name="encoding">The encoding for the stream.</param>
    public NoCloseStreamWriter(Stream stream, Encoding encoding)
        : base(stream, encoding)
    {
    }

    /// <summary>
    /// Creates a new stream writer object using default encoding.
    /// </summary>
    /// <param name="stream">The underlying stream to write to.</param>
    /// <param name="encoding">The encoding for the stream.</param>
    public NoCloseStreamWriter(Stream stream)
        : base(stream)
    {
    }

    /// <summary>
    /// Disposes of the stream writer.
    /// </summary>
    /// <param name="disposing">True to dispose managed objects.</param>
    protected override void Dispose(bool disposeManaged)
    {
        // Dispose the stream writer but pass false to the dispose
        // method to stop it from closing the underlying stream
        base.Dispose(false);
    }
}

If you look in Reflector / ILSpy you will find that the closing of the base stream is actually done in Dispose(true), and when close is called it just calls Dispose which calls Dispose(True), from the code there should be no other side effects, so the class above works nicely.

You might want to add all the constructors though, i have just added 2 here for simplicity.

Solution 3:

From StreamWriter.Close()

public override void Close()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

From TextWriter.Dispose() (which StreamWriter inherits)

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

They are thus, identical.