在类中析构函数和Finalize方法之间有什么区别?
我最近发现Visual Studio 2008认为析构函数与Finalize方法同义,这意味着Visual Studio不允许您同时在类中定义这两种方法。
例如,以下代码片段:
class TestFinalize
{
~TestFinalize()
{
Finalize();
}
public bool Finalize()
{
return true;
}
}
在析构函数中调用Finalize时出现以下错误:
以下方法或属性之间的调用不明确: 'TestFinalize .~TestFinalize()'和'TestFinalize.Finalize()'
如果对Finalize的调用被注释掉,则会出现以下错误:
类型'ManagementConcepts.Service.TestFinalize'已经定义了一个名为的成员 'Finalize'使用相同的参数类型
答案 0 :(得分:63)
维基百科对destructor文章中的终结者与finalizer之间的区别进行了一些很好的讨论。
C#真的没有“真正的”析构函数。语法类似于C ++析构函数,但它确实是终结器。您在示例的第一部分中正确编写了它:
~ClassName() { }
以上是Finalize
函数的语法糖。它确保基本中的终结器保证运行,但在其他方面与覆盖Finalize
函数完全相同。这意味着当你编写析构函数语法时,你真的在编写终结器。
According to Microsoft,终结器引用垃圾收集器在收集(Finalize
)时调用的函数,而析构函数是你执行结果的代码(语法糖变为Finalize
)。它们非常接近于微软应该从未做过区分的事情。
微软使用C ++的“析构函数”这一术语具有误导性,因为在C ++中,只要对象被删除或从堆栈中弹出就会在同一个线程上执行,而在C#中,它在另一个线程上的另一个线程上执行时间。
答案 1 :(得分:59)
C#中的析构函数覆盖System.Object.Finalize
方法。您必须使用析构函数语法来执行此操作。手动覆盖Finalize
会给您一条错误消息。
基本上,您尝试使用Finalize
方法声明的方法是hiding基类的方法。它将导致编译器发出警告,该警告可以使用new
修饰符进行静音(如果它将起作用)。这里需要注意的重要一点是,不能同时override
并同时声明一个名称相同的new
成员,因此同时拥有析构函数和{{{ 1}}方法会导致错误(但是可以,虽然不推荐,但如果您没有声明析构函数,则声明Finalize
方法。)
答案 2 :(得分:18)
Found here: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html
析构
它们是包含对象清理代码的特殊方法。 您无法在调用代码时显式调用它们 GC隐含地。在C#中,它们的名称与前面的类名相同 通过
~
标志。象 -Class MyClass { ~MyClass() { ..... } }
在VB.NET中,通过覆盖Finalize来实现析构函数 System.Object类的方法。
处置
这些就像类中的任何其他方法一样,可以调用 明确但他们有一个清理对象的特殊目的。 在dispose方法中,我们为对象编写清理代码。它是 重要的是我们释放了处置中的所有非托管资源 方法如数据库连接,文件等。实现类 dispose方法应该实现IDisposable接口.A Dispose方法 应该为它的对象调用GC.SuppressFinalize方法 如果该类有desturctor,因为它已经完成了 工作来清理对象,然后没有必要的垃圾 collector来调用对象的Finalize方法。参考: http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx
- 醇>
的Finalize
Finalize方法可以作为清理资源的保障措施 不调用Dispose方法的事件。你应该只 实现Finalize方法来清理非托管资源。您 不应该为托管对象实现Finalize方法,因为 垃圾收集器自动清理托管资源。 Finalize方法由GC隐式调用,因此你不能 从你的代码中调用它。
注意:在C#中,Finalize方法无法覆盖,所以你必须这样做 使用析构函数,其内部实现将覆盖 在MSIL中完成方法。但是在VB.NET中,Finalize方法可以 覆盖因为它确实支持析构函数方法。