[ACCEPTED]-wrapping MemoryStream in a using-stream

Accepted answer
Score: 31

The C# idiom is that if an object implements 35 IDisposable then you use a using block. This will allow 34 all resources being used by the object be 33 disposed of properly. You're not suppose 32 to know the implementation details of MemoryStream. What 31 you do know is that it implements IDisposable so you 30 should dispose of it properly. Further, you 29 think that you know now that it doesn't 28 need to free any resources but how do you 27 know that in the future MemoryStream won't change its 26 underlying implementation so that it does 25 use resources that need to be freed using 24 Dispose? You don't, so since it implements IDispoable you 23 have more future-proof code by just using 22 the pattern now. Second, what if you change 21 your code in the future to use a different 20 type of Stream that does have managed resources? By 19 wrapping the MemoryStream in a using block now you reduce 18 maintenance issues in the future; again, this 17 is the correct way to use objects, and specifically 16 Streams that implement IDisposable. Third, it's a clear way 15 to signal to readers that you are done using 14 the object; it's what readers of your code 13 will expect to see when they see you are 12 using objects that implement IDisposable. Finally, this 11 is the current implementation of MemoryStream.Dispose:

protected override void Dispose(bool disposing) {
    try {
        if (disposing) {
            this._isOpen = false;
            this._writable = false;
            this._expandable = false;
        }
     }
     finally {
         base.Dispose(disposing);
     }
}

So, this 10 marks the stream as closed, not-writable 9 and not-growable. If somehow someone else 8 got a hold of a reference to the same MemoryStream, it 7 now becomes unusable to them which could 6 be a good thing. But this is really the 5 least important issue; the implementation 4 details don't matter.

Use a using block because 3 MemoryStream implement IDispoable. Don't not use a using block because 2 you think that MemoryStream doesn't have any resources 1 that need to be freed.

Score: 7

A guideline is that if it implements IDisposable 4 then you should dispose of it. You're just 3 working with an API and are not aware of 2 the implementation so you've no reason to 1 not put it in a using block.

Score: 5

If the class implements IDisposable, it 10 should be disposed.

You don't need to bother 9 guessing whether it does anything of significance 8 or not - that's for the class to decide 7 and implement. If the class doesn't do 6 anything when the object gets disposed, then 5 there's really no cost anyway, so there's 4 no harm.

Encapsulation is one of the cornerstones 3 of object oriented development. Why go 2 out of your way to break that, especially 1 if there's no good reason?

Score: 5

Having had a quick look in Reflector, it appears 10 that Dispose on the MemoryStream does little other than to 9 mark the stream as not being open, writeable 8 or expandable.

Having said that, as a general 7 approach, you should probably keep with 6 the dispose pattern; escpecially as Streams all 5 follow the "decorator" approach 4 and should be easy to swap out for each 3 other, or wrap one with another. Today's 2 MemoryStream may get swapped out for another stream 1 that does care tomorrow.

Score: 3

You do not lose anything by wrapping the 2 memory stream in a using block, so if there's 1 doubt, just do it. :)

Score: 3

As Charlie said, it is a recommended practice to Dispose 6 of all objects of classes that implements 5 IDisposable.

If you look into the implementation 4 of MemoryStream.Dispose(bool) (which is 3 called by Stream.Dispose()), it becomes 2 obvious you should be disposing of it since 1 it updates a few control flags:

protected override void Dispose(bool disposing)
{
    try
    {
        if (disposing)
        {
            this._isOpen = false;
            this._writable = false;
            this._expandable = false;
        }
    }
    finally
    {
        base.Dispose(disposing);
    }
}

More Related questions