I've been told that System.IO.MemoryStream need not be wrapped in a using block because there is no underlying resource, this kinda goes against what i've always been told about streams ("if in doubt, use a using").
Is this true? Why then does MSDN example use one (summarized below)?
using(MemoryStream memStream = new MemoryStream(100))
{
// do stuff
}
You do not lose anything by wrapping the memory stream in a using block, so if there's doubt, just do it. :)
Having had a quick look in Reflector, it appears that
Dispose
on theMemoryStream
does little other than to mark the stream as not being open, writeable or expandable.Having said that, as a general approach, you should probably keep with the dispose pattern; escpecially as
Stream
s all follow the "decorator" approach and should be easy to swap out for each other, or wrap one with another. Today'sMemoryStream
may get swapped out for another stream that does care tomorrow.A guideline is that if it implements IDisposable then you should dispose of it. You're just working with an API and are not aware of the implementation so you've no reason to not put it in a using block.
As Charlie said, it is a recommended practice to Dispose of all objects of classes that implements IDisposable.
If you look into the implementation of MemoryStream.Dispose(bool) (which is called by Stream.Dispose()), it becomes obvious you should be disposing of it since it updates a few control flags:
If the class implements IDisposable, it should be disposed.
You don't need to bother guessing whether it does anything of significance or not - that's for the class to decide and implement. If the class doesn't do anything when the object gets disposed, then there's really no cost anyway, so there's no harm.
Encapsulation is one of the cornerstones of object oriented development. Why go out of your way to break that, especially if there's no good reason?
The C# idiom is that if an object implements
IDisposable
then you use ausing
block. This will allow all resources being used by the object be disposed of properly. You're not suppose to know the implementation details ofMemoryStream
. What you do know is that it implementsIDisposable
so you should dispose of it properly. Further, you think that you know now that it doesn't need to free any resources but how do you know that in the futureMemoryStream
won't change its underlying implementation so that it does use resources that need to be freed usingDispose
? You don't, so since it implementsIDispoable
you have more future-proof code by just using the pattern now. Second, what if you change your code in the future to use a different type ofStream
that does have managed resources? By wrapping theMemoryStream
in ausing
block now you reduce maintenance issues in the future; again, this is the correct way to use objects, and specificallyStream
s that implementIDisposable
. Third, it's a clear way to signal to readers that you are done using the object; it's what readers of your code will expect to see when they see you are using objects that implementIDisposable
. Finally, this is the current implementation ofMemoryStream.Dispose
:So, this marks the stream as closed, not-writable and not-growable. If somehow someone else got a hold of a reference to the same
MemoryStream
, it now becomes unusable to them which could be a good thing. But this is really the least important issue; the implementation details don't matter.Use a
using
block becauseMemoryStream
implementIDispoable
. Don't not use ausing
block because you think thatMemoryStream
doesn't have any resources that need to be freed.