IDisposable问题
说我有以下内容:
public abstract class ControlLimitBase : IDisposable { } public abstract class UpperAlarmLimit : ControlLimitBase { } public class CdsUpperAlarmLimit : UpperAlarmLimit { }
两个问题:
我的IDisposable成员实际上会被叫到,我有点困惑。 当CdsUpperAlarmLimit的实例超出范围时,它们会被调用吗?
2.如何处理在CdsUpperAlarmLimit类中创建的对象? 这也应该来自IDisposable吗?
Dispose()
永远不会自动调用 – 它取决于代码的实际使用方式。
1.)当你专门调用Dispose()
时调用Dispose()
:
myAlarm.Dispose();
2.)使用您的类型的实例在using
块的末尾调用Dispose()
。
using(var myAlarm = new CdsUpperAlarmLimit()) { }
using
块是try/finally
块的语法糖,在try/finally
块中对“正在使用”的对象调用Dispose()
。
-
不,
IDisposable
不会被自动调用。 您通常using
语句调用Dispose
,如下所示:using (ControlLimitBase limit = new UpperAlarmLimit()) { // Code using the limit }
这实际上是一个try / finally块,所以当你离开块时会调用
Dispose
。 -
CdsUpperAlarmLimit
已间接实现IDisposable
。 如果您按照正常模式在非密封类中实现IDisposable
,您将覆盖void Dispose(bool disposing)
并在那里处理您的组合资源。
请注意,垃圾收集器不会调用Dispose
本身 – 尽管它可以调用终结器 。 您应该很少使用终结器,除非您可以直接处理非托管资源。
说实话,我经常发现值得尝试更改设计以避免需要在类中保持非托管资源 – 在一般情况下正确实现IDisposable
坦白说是一种痛苦。 如果您的类是密封的(不需要额外的方法;只需实现Dispose()
方法)也不是那么糟糕 – 但它仍然意味着您的客户需要知道它,以便他们可以使用适当的using
语句。
IDisposable
有一个成员, Dispose()
。
当您选择调用它时会调用此方法。 最典型的是框架使用using
block syntactic sugar为你完成的。
当我的IDisposable成员实际上被调用时,我有点困惑。 当CdsUpperAlarmLimit的实例超出范围时,它们会被调用吗?
不。当你使用construct作为时,它被调用:
using(var inst = new CdsUpperAlarmLimit()) { //... }//<-------- here inst.Dispose() gets called.
但如果你写这个,它就不会被调用:
{ var inst = new CdsUpperAlarmLimit(); //... }//<-------- here inst.Dispose() does NOT get called.
但是,您也可以这样写:
var inst = new CdsUpperAlarmLimit(); using( inst ) { //... }//<-------- here inst.Dispose() gets called.
最佳实践建议在非密封类中实现Dispose()
方法时,您应该有一个虚拟方法来覆盖派生类。
在此处阅读更多关于Dispose模式的信息http://www.codeproject.com/KB/cs/idisposable.aspx
使用IDisposable对象时,以这种方式使用它总是好的:
using(var disposable = new DisposableObject()) { // do you stuff with disposable }
运行using块后,将在IDisposable对象上调用Dispose方法。 否则,您需要手动调用Dispose。
- 当有人打电话时。
.Dispose
它。 - 不,它已经通过inheritance实现了它。
当您想要指示您的资源具有必须显式卸载和清除的依赖项时,才会实现IDisposable。 因此,永远不会自动调用IDisposable(就像垃圾收集一样)。
通常,要处理IDisposable,您应该将它们的用法包装在using块中
using(var x = new CdsUpperAlarmLimit()) { ... }
这编译为:
CdsUpperAlarmLimit x = null; try { x = new CdsUpperAlarmLimit(); ... } finally { x.Dispose(); }
所以,回到主题,如果你的类型CdsUpperAlarmLimit正在实现IDisposable,它就向全世界说:“我有必须处理的东西”。 常见的原因是:
- CdsUpperAlarmLimit保留一些其他IDisposable资源(如FileStreams,ObjectContexts,Timers等),当CdsUpperAlarmLimit完成使用时,它需要确保FileStreams,ObjectContexts,Timers等也被调用Dispose。
- CdsUpperAlarmLimit正在使用非托管资源或内存,必须在完成后清理或者内存泄漏