Consider the following code:
using (var ms = new MemoryStream())
{
using(var writer = BinaryWriter(ms))
{
writer.Write(/*something*/);
writer.Flush();
}
Assert.That(ms.Length > 0); // Throws ObjectDisposedException
}
On the one hand, a disposable object should dispose of it's resources; I get that, but on the other hand, the object didn't create and doesn't own this resource, it was provided -> calling code should take responsibility for it... no?
I can't think of any other situations like this, but is it a consistent pattern in the framework for any class receiving disposable objects to dispose of them on its own dispose?
There is an implicit assumption that you will only have one writer per stream, so the writer assumes ownership of the stream for convenience - you then obly have one thing to clean up.
But I agree; this is not always true, and often inconvenient. Some implementations (DeflateStream, GZipStream, for example) allow you to choose. Otherwise the only real option is to inject a dummy stream between the writer and the underlying stream; IIRC there is a NonClosingStreamWrapper in Jon Skeet's "MiscUtil" library that does exactly this: http://www.yoda.arachsys.com/csharp/miscutil/
Usage would be something like:
using (var ms = new MemoryStream())
{
using(var noClose = new NonClosingStreamWrapper(ms))
using(var writer = BinaryWriter(noClose))
{
writer.Write(/*something*/);
writer.Flush();
}
Assert.That(ms.Length > 0);
}
I totally agree with you. This is not consistent behavior but it is how it has been implemented. There are comments at the end of the documentation about this behavior which is not very intuitive. All stream writers just take ownership of the underlying stream and dispose it. Personally I always nest my using
statement like this:
using (var ms = new MemoryStream())
using(var writer = BinaryWriter(ms))
{
writer.Write(/*something*/);
}
so that a code like the one you put in the Assert shouldn't be written.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With