将MemoryStream包装在一个使用中

时间:2010-01-08 16:48:41

标签: c# .net stream

我被告知System.IO.MemoryStream不需要包含在使用块中,因为没有底层资源,这种情况违背了我一直被告知的关于流的内容( “如果有疑问,请使用使用”)。

这是真的吗?为什么MSDN example会使用一个(总结如下)?

using(MemoryStream memStream = new MemoryStream(100))
{
            // do stuff
}

6 个答案:

答案 0 :(得分:26)

C#习惯用法是,如果一个对象实现IDisposable,那么你使用using块。这将允许正确处理对象使用的所有资源。您不应该知道MemoryStream的实施细节。你所知道的是它实现了IDisposable所以你应该妥善处理它。此外,您认为您现在知道它不需要释放任何资源,但您如何知道将来MemoryStream将不会更改其底层实现,以便它确实使用需要释放的资源使用Dispose?你不这样做,所以既然它实现了IDispoable,你就可以通过现在使用模式获得更多面向未来的代码。其次,如果您将来更改代码以使用具有托管资源的其他类型Stream,该怎么办?通过将MemoryStream包裹在using块中,您可以在将来减少维护问题;再次,这是使用对象的正确方法,特别是实现Stream的{​​{1}}。第三,它是一种向读者发出信号的明确方式,即您已经完成了使用该对象;这是您的代码的读者在看到您使用实现IDisposable的对象时会看到的内容。最后,这是IDisposable

的当前实现
MemoryStream.Dispose

因此,这标志着流是封闭的,不可写的,不可增长的。如果其他人以某种方式获得对同一protected override void Dispose(bool disposing) { try { if (disposing) { this._isOpen = false; this._writable = false; this._expandable = false; } } finally { base.Dispose(disposing); } } 的引用,它现在变得无法使用,这可能是一件好事。但这确实是最不重要的问题;实施细节无关紧要。

使用MemoryStream阻止,因为using实施MemoryStream。不要使用IDispoable块,因为您认为using没有任何需要释放的资源。

答案 1 :(得分:6)

指南是,如果它实现了IDisposable,那么你应该处理它。您只是使用API​​并且不了解实现,因此您没有理由不将其放入使用块中。

答案 2 :(得分:5)

快速查看Reflector后,Dispose上的MemoryStream似乎除了将流标记为不可打开,可写或可展开之外没什么作用。

话虽如此,作为一般方法,你应该保持处置模式;特别是Stream都遵循“装饰者”的方法,应该很容易互换,或者用另一个包换。今天的MemoryStream可能会换掉另一个明天关心的流。

答案 3 :(得分:4)

如果该类实现了IDisposable,则应将其处理掉。

你不需要费心去猜测它是否有意义 - 这是由班级来决定和实施的。如果在对象被处理时该类没有做任何事情,那么无论如何都没有任何成本,所以没有任何伤害。

封装是面向对象开发的基石之一。为什么要打破这种局面,特别是如果没有充分的理由呢?

答案 4 :(得分:3)

通过将内存流包装在using块中,您不会丢失任何内容,因此如果有疑问,请执行此操作。 :)

答案 5 :(得分:3)

作为Charlie said,建议使用Dispose实现IDisposable的所有类的对象。

如果你看一下MemoryStream.Dispose(bool)(由Stream.Dispose()调用)的实现,很明显你应该处理它,因为它更新了一些控制标志:

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