什么时候应该创build一个析构函数?
例如:
public class Person { public Person() { } ~Person() { } }
什么时候应该手动创build一个析构函数? 你什么时候需要创build一个析构函数?
C#语言调用这些“析构函数”,但大多数人称它们为“终结符”,因为这是它们的.NET名称,并且减less了与C ++析构函数(这是非常不同的)的混淆。
如何实现IDisposable和终结者:3简单的规则
更新:这个问题是我的博客在2015年5月的主题 。 感谢您的好问题! 在博客中看到一大堆人们普遍认为最终确定的谎言。
什么时候应该手动创build一个析构函数?
几乎从不。
通常情况下,只有当你的类持有一些昂贵的非托pipe资源时,才会创build一个析构函数,这个资源必须在对象消失时清理掉。 最好使用一次性模式来保证资源的清理。 一个析构函数实质上是一个保证,如果你的对象的使用者忘记了处理它,那么这个资源最终还是会被清理掉。 (也许。)
如果你使析构函数非常小心,并了解垃圾收集器如何工作 。 析构函数真的很奇怪 :
- 他们不会跑在你的线上; 他们在自己的线程上运行。 不要造成死锁!
- 从析构函数抛出的未处理exception是个坏消息。 这是在自己的线程; 谁会去捕捉它?
- 在构造函数启动之后但在构造函数完成之前 ,可以在对象上调用析构函数。 正确书写的析构函数不会依赖构造函数中build立的不variables。
- 析构函数可以“复活”一个对象,使一个死对象再次活着。 这真的很奇怪。 不要这样做。
- 析构函数可能永远不会运行; 你不能依赖于被安排的对象。 它可能会,但这不是一个保证。
在析构函数中几乎没有什么是正确的。 真的,真的很小心。 写一个正确的析构函数是非常困难的。
你什么时候需要创build一个析构函数?
testing处理析构函数的编译器部分时。 我从来没有需要在生产代码中这样做。 我很less编写操纵非托pipe资源的对象。
它被称为“终结器”,通常应该只为其状态(即:字段)包含非托pipe资源的类(即:通过p / invoke调用检索到的句柄的指针)创build一个。 但是,在.NET 2.0和更高版本中,实际上有更好的方法来处理清理非托pipe资源: SafeHandle 。 鉴于此,你几乎不需要再写一个终结器。
你不需要一个,除非你的类维护非托pipe资源,如Windows文件句柄。
它被称为析构函数/终结器,通常在实现Disposed模式时创build。
当你的类的用户忘记调用Dispose时,这是一个后备解决scheme,以确保(最终)你的资源被释放,但是你不能保证什么时候调用析构函数。
在这个堆栈溢出问题中 ,接受的答案正确地显示了如何实现configuration模式。 这只有当你的类包含垃圾收集器没有pipe理清理自己的任何unhandeled资源时才需要。
一个好的做法是不实现一个终结器,也不要给这个类的用户手动处理对象以释放资源的可能性。
当你拥有非托pipe资源时,当你的对象消失时,你需要确保它们会被清理干净。 好的例子是COM对象或文件处理程序。
我已经使用了一个析构函数(仅用于debugging目的),以查看在WPF应用程序范围内是否从内存中清除了一个对象。 我不确定垃圾收集是否真正从内存中清除对象,这是一个很好的validation方法。
析构函数提供了一种释放封装在类中的非托pipe资源的隐式方法,当GC接近它时它们会被调用,并隐式地调用基类的Finalize方法。 如果您使用了大量的非托pipe资源,最好提供一个通过IDisposable接口释放这些资源的明确方法。 请参阅C#编程指南: http : //msdn.microsoft.com/en-us/library/66x5fx1b.aspx