在C#中,析构函数和Finalize方法在类中有什么不同?
在一个类的析构函数和Finalize方法之间有什么区别,如果有的话?
我最近发现Visual Studio 2008认为析构函数与Finalize方法同义,这意味着Visual Studio不会让您同时在类中定义两个方法。
例如,下面的代码片段:
class TestFinalize { ~TestFinalize() { Finalize(); } public bool Finalize() { return true; } }
给析构函数中的Finalize调用提供以下错误:
这个调用在下面的方法或属性之间是不明确的:'TestFinalize。〜TestFinalize()'和'TestFinalize.Finalize()'
如果Finalize的调用被注释掉了,则会出现以下错误:
types'ManagementConcepts.Service.TestFinalize'已经使用相同的参数types定义了一个名为'Finalize'的成员
C#中的析构函数重写System.Object.Finalize
方法。 您必须使用析构函数语法来执行此操作。 手动覆盖Finalize
会给你一个错误信息。
基本上你正在试图用你的Finalize
方法声明是隐藏基类的方法。 这将导致编译器发出一个警告,可以使用new
修饰符(如果它正在工作)沉默。 这里要注意的重要一点是,你不能同时override
和声明一个同名的new
成员,所以同时使用析构函数和Finalize
方法会导致错误(但是你可以 ,尽pipe不推荐,声明如果你没有声明一个析构函数,一个public new void Finalize()
方法)。
维基百科有一些关于终结者文章中的终结器和析构函数之间的区别的讨论。
C#真的没有“真正的”析构函数。 该语法类似于C ++析构函数,但它确实是一个终结器。 你在你的例子的第一部分中正确地写了它:
~ClassName() { }
以上是Finalize
函数的语法糖。 它可以确保基础中的终结器保证运行,但在其他方面与重写Finalize
函数相同。 这意味着当你编写析构函数的语法时,你确实正在编写终结器。
根据微软的说法 ,终结器指的是垃圾收集器在收集时调用的函数( Finalize
),而析构函数是执行结果的一小段代码(成为Finalize
的语法糖)。 他们是如此接近于微软应该从未作出过这样的区分。
微软使用C ++的“析构函数”这个术语是有误导性的,因为在C ++中,只要对象被删除或popup堆栈,就会在同一个线程上执行,而在C#中则是在另一个单独的线程上执行。
在这里find:http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html
析构函数
它们是包含对象清理代码的特殊方法。 您不能在代码中明确地调用它们,因为它们被GC隐式调用。 在C#中,它们与
~
符号前面的类名称相同。 喜欢-Class MyClass { ~MyClass() { ..... } }
在VB.NET中,析构函数是通过覆盖System.Object类的Finalize方法来实现的。
部署
这些就像其他类中的方法一样,可以明确地调用,但是它们有一个特殊的目的是清理对象。 在处理方法中,我们为对象编写清理代码。 重要的是我们释放了像数据库连接,文件等处理方法中的所有非托pipe资源。实现dispose方法的类应该实现IDisposable接口。Dispose方法应该为它正在处理的对象调用GC.SuppressFinalize方法,如果class已经具有desturctor,因为它已经完成了清理对象的工作,所以垃圾收集器不需要调用对象的Finalize方法。 参考: http : //msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx
最终确定
如果Dispose方法未被调用,则Finalize方法可用作清理资源的安全措施。 你只应该实现一个Finalize方法来清理非托pipe资源。 您不应该为托pipe对象实现Finalize方法,因为垃圾回收器会自动清理托pipe资源。 Finalize方法由GC隐式调用,因此不能从代码中调用它。
注意:在C#中,Finalize方法不能被覆盖,所以你必须使用析构函数,它的内部实现将覆盖MSIL中的Finalize方法。但是在VB.NET中,Finalize方法可以被覆盖,因为它支持析构函数方法。
更新: 有趣的半相关线程在这里 。