IDisisposable应该级联应用吗?

Joh*_*lph 14 .net c# idisposable

这是一个相当基本的问题,但我仍然在努力解决它.

当您希望在对象最终被垃圾收集之前允许对象的用户释放底层资源(例如套接字等)时,实现IDisposable.

当我有一个持有DbConnection(实现IDisposable)的类时,我的类是否也需要实现IDisposable并将调用链接到DbConnection或它拥有的任何其他IDisposable对象?否则,只有当我的类是GarbageCollected时才会释放DbConnections资源,从而删除它对连接的引用,GC将完成DbConnection.

tyl*_*erl 10

是的,如果你控制一次性物品,你总是可以实现IDisposable.总是.如果你不这样做,你的代码就不会破坏,但如果不这样做,它就会失去拥有一次性物品的目的.

GC优化的一般规则是:

  • 任何控制不由GC管理的对象的类都必须实现终结器(通常也应该实现IDisposable).这是"顶级"一次性类通常来自的地方 - 它们通常将HANDLE控制为窗口,插座,互斥体或者你拥有的东西.
  • 任何实例化IDisposable成员的类都应该实现IDisposable本身,并正确地对其成分进行Dispose().
  • 任何实例化IDisposeable对象的函数都应该在使用它时正确Dispose().不要让它只是超出范围.

如果您为自己编写应用程序,可能会忽略或忽略这些规则,但在向其他人分发代码时,您应该专业并遵守规则.

这里的逻辑是,当您在GC视图之外控制内存时,GC引擎无法正确管理您的内存使用情况.例如,在.NET堆上,您可能只有一个4字节的指针,但在非托管的域中,您可以指向200 MB的内存.GC引擎在你有几十个之前不会尝试收集它们,因为它只看到几个字节; 而在现实世界中,它看起来很像内存泄漏.

因此,规则是,当您使用它时,非托管内存应立即释放(IDisposable链为您执行此操作),而GC引擎会随时释放托管内存.

  • 这确实应该通过语言更好地处理——必须在整个类层次结构中链接 IDisposable/Dispose 是荒谬且乏味的。 (2认同)

Dav*_*vid 6

是的,如果需要处理它使用的任何对象,那么你的类需要是IDisposable.一个例子是StreamReader.它实现了IDisposable,因此它可以处理其关联的流对象.