如果一个成员是 IDisposable,我们是否应该实现 IDisposable?
我想是的。但看一下 ASP.NET 中的内置类:
public sealed class HttpPostedFile
{
public Stream InputStream { get; } // Stream implements IDisposable
// other properties and methods
}
假设我有一个名为 file
的 HttpPostedFile
实例。由于没有显式调用的 Dispose 方法,所以在析构之前不会调用 file.InputStream.Dispose() ,我认为这违背了 file.InputStream.Dispose()
的初衷代码> IDisposable 。我认为正确的实现应该包含标准的 IDisposable 实现。因此,如果其中一个成员实现了 IDisposable,则该类也需要实现它。
你有什么意见?好像有点复杂。
I think so. But take a look at a built-in class in ASP.NET:
public sealed class HttpPostedFile
{
public Stream InputStream { get; } // Stream implements IDisposable
// other properties and methods
}
Suppose I have an instance of HttpPostedFile
called file
. Since there is no Dispose
method to explicitly invoke, file.InputStream.Dispose()
won't be invoked until it's destructed, which I think goes against the original intention of IDisposable
. I think the correct implementation should contain a standard IDisposable
implementation. So, if one of the members implements IDisposable
, the class needs to implement it too.
What are your opinions? It seems to be a bit complicated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,如果您拥有属性所代表的资源,则应该实现
IDisposable
- 请参阅此问题用于讨论该主题。我想说,因为 HttpPostedFile 是在处理 HTTP 请求期间实例化的,所以它不拥有该流,因此不会处置它。当 HTTP 请求处理完成时,该流将被释放。
In general, you should implement
IDisposable
if you own the resource represented by the property - see this question for a discussion on this subject.I'd say that because HttpPostedFile is instantiated during processing of an HTTP request, it doesn't own the stream, and hence doesn't dispose it. The stream will be disposed when the HTTP request processing finishes.
如果您的类创建一个或多个
IDisposable
对象并保存对它们的唯一引用,那么您的类几乎肯定应该实现IDisposable
并处置IDisposable
它创建的对象。如果一个或多个IDisposable
对象将被传递到类的构造函数中,那么您需要考虑以下几种情况:IDisposable
已经完成了,并且肯定会知道何时不再需要它(您的类的语义会让他知道您已经完成了)。对于场景 #1,您无需实现
IDisposable
,尽管实现一个不执行任何操作的IDisposable
处理程序并让您的消费者使用它可能不是一个坏主意,以防将来出现另一种情况。对于场景#2,您的对象应该拥有
IDisposable
的所有权,并在完成后Dispose
它。我真的不喜欢让对象无条件拥有 IDisposable 的所有权;我更喜欢按照#3 中的方式实现。有两种处理#3 的方法。我更喜欢的是让您的对象采用一个参数(
Boolean
或enum
)以及IDisposable
,指示它是否是应该取得IDisposable
的所有权。你的类无条件实现IDisposable
;该实现会处理它已拥有所有权的任何对象,但不会处理尚未拥有的对象。另一种方法是让两个子类具有共同的基类 - 一个子类实现 IDisposable,而另一个则不实现。我更喜欢前一种模式,因为它允许添加一种方法来用新的(它可能会也可能不会拥有所有权)替换 IDisposable 。例如,如果我要实现具有Image
属性的控件,我将有一个SetImage
方法,该方法带有一个参数来指定该控件是否应拥有传入的图像;该方法将Dispose
旧图像(如果它拥有它),然后可以获取或不获取新图像的所有权。场景 #4 很复杂;处理它的最佳方法可能是让您的对象通过引发
Dispose
事件来实现IDisposable
。您的创建者可以使用该事件来Dispose
该对象(如果您是最后一个使用该对象的人),或者调整标志或计数器,以便其他代码知道该对象不应留在您的设备上。代表。If your class creates one or more
IDisposable
objects and holds the only references to them, then your class should almost certainly implementIDisposable
and dispose theIDisposable
objects it created. If one or moreIDisposable
objects will be passed into the constructor of your class, then you need to consider a few scenarios:IDisposable
after you're done with it, and will certainly know when it's no longer needed (the semantics of your class would let him know you're done with it).IDisposable
after you're done with it, and may not know when you're going to be done with it.For scenario #1, there's no need for you to implement
IDisposable
, though it might not be a bad idea to implement a do-nothingIDisposable
handler and have your consumers use it, in case another scenario applies in future.For scenario #2, your object should take ownership of the
IDisposable
, and shouldDispose
it when done. I don't really like having objects take unconditional ownership ofIDisposable
s; I prefer to implement things as in #3.There are two ways of handling #3. The one I prefer is for your object to take a parameter (either a
Boolean
or anenum
) along with theIDisposable
, indicating whether it is supposed to take ownership of theIDisposable
. Your class unconditionally implementsIDisposable
; the implementation disposes of any objects it has taken ownership of, but not those it hasn't. An alternative is to have two subclasses with a common base class - one subclass implementsIDisposable
and the other does not. I prefer the former pattern, because it allows for the addition of a method to replace anIDisposable
with a new one (of which it may or may not take ownership). For example, if I were implementing a control with anImage
property, I would have aSetImage
method which with a parameter to specify whether the control should own the passed-in image; that method wouldDispose
the old image if it owned it, and could then either take ownership of the new image or not.Scenario #4 is complicated; the best way to handle it is probably for your object to implement
IDisposable
by raising aDisposed
event. Your creator can use that event to do eitherDispose
the object if you were the last one using it, or adjust a flag or counter so that other code will know the object shouldn't be left undisposed on your behalf.这取决于。
Stream
也由TextStream
实现(可能在StringBuilder
之上),因此不需要非托管资源。HttpPostedFile
可能根本不使用任何非托管资源,因此可以安全地推迟解构,直到垃圾收集器认为合适。It depends.
Stream
is also implemented byTextStream
(possibly on top ofStringBuilder
), so no unmanaged resources are required.HttpPostedFile
may not use any unmanaged resources at all, so it's safe to postpone deconstruction until the garbage collector sees fit.