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()

  1. 不, IDisposable不会被自动调用。 您通常 using语句调用Dispose ,如下所示:

     using (ControlLimitBase limit = new UpperAlarmLimit()) { // Code using the limit } 

    这实际上是一个try / finally块,所以当你离开块时会调用Dispose

  2. 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。

  1. 当有人打电话时。 .Dispose它。
  2. 不,它已经通过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正在使用非托管资源或内存,必须在完成后清理或者内存泄漏