akj*_*shi 4 .net c# wpf idisposable finalizer
我在我的类中实现了Finalize和Dispose,我在我的父类上实现了IDisposable并覆盖了我的子类中的Dispose(bool)重载.我不确定
这两件事都是在这里给出的例子中完成的 -
虽然此MSDN文章中的示例没有这两个中的任何一个 - http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx
而MSDN中的这个例子并不完整 - http://msdn.microsoft.com/en-us/library/ms182330.aspx
终结器非常有用.您链接到的文档并不完全有用 - 它提供以下相当循环的建议:
仅对需要完成的对象实施Finalize
这是提出问题的一个很好的例子,但它并没有多大帮助.
在实践中,绝大多数时候你不想要终结者.(.NET开发人员必须经历的学习曲线之一是发现在大多数地方他们认为他们需要终结器,但他们没有.)您已将此标记为(除其他事项外)WPF问题,以及我想说将终结器放在UI对象上几乎总是错误的.(因此,即使您处于需要终结器的异常情况之一,该工作也不属于与WPF有关的代码附近的任何地方.)
对于终结器看起来可能有用的大多数场景而言,结果并非如此,因为当你的终结器运行时,它已经为时已晚,无法做任何有用的事情.
例如,尝试对对象引用的任何对象执行任何操作通常是个坏主意,因为在终结器运行时,这些对象可能已经完成.(.NET不保证终结器的运行顺序,所以你根本无法知道你引用的对象是否已经完成.)在终结器已经完成的对象上调用方法是个坏主意.已经运行了.
如果你有知道一些对象肯定尚未敲定的一些方法,那么它是安全的使用它,但是这是一个非常不寻常的情况是在(...除非有问题的对象没有终结,使使用上没有终结资源本身.但在这种情况下,它可能不是一个对象你真正需要做的事情,当你自己的对象将客场).
终结器似乎有用的主要情况是互操作:例如,假设您正在使用P/Invoke调用一些非托管API,并且该API会返回一个句柄.也许还有一些其他API需要调用来关闭该句柄.由于这是所有非托管的东西,.NET GC不知道这些句柄是什么,确保它们被清理是你的工作,此时终结器是合理的......除了在实践中,它几乎总是最好的SafeHandle为那个场景使用a .
在实践中,我发现自己使用终结器的唯一地方是:a)旨在调查GC功能的实验,以及b)旨在发现某些特定对象在系统中使用的一些诊断代码.这两种代码都不应该最终投入生产.
所以,你是否需要"在子类中实现终结器"的答案是:如果你需要问,那么答案是否定的.
至于是否复制旗帜......其他答案在这里提供了相互矛盾的建议.要点是1)你需要打电话给基地Dispose,2)你Dispose需要是幂等的.(即,如果它被调用一次,两次,5次,100次也无关紧要 - 如果它不止一次被调用它就不应该抱怨.)你可以自由地实现它,无论你喜欢什么 - 一个布尔标志是一种方法,但我经常发现null在我的Dispose方法中设置某些字段就足够了,此时不需要单独的布尔标志 - 你可以告诉它Dispose已经被调用,因为你已经将这些字段设置为null.
很多指导IDisposable是非常无益的,因为它解决了你需要终结器的情况,但这实际上是一个非常不寻常的情况.这意味着很多人编写的IDisposable实现远比必要复杂得多.在实践中,大多数课程都会调用Stephen Cleary在jpierson链接的文章中称为"1级"的类别.而对于这些,你并不需要所有的GC.KeepAlive,GC.SuppressFinalize以及Dispose(bool)东西,杂波了大部分的例子.大多数时候,生活实际上要简单得多,正如Cleary对这些"1级"类型的建议所显示的那样.