终结者和析构者,维基百科说什么?

时间:2011-05-04 11:37:39

标签: c# destructor finalizer

据我所知,有两个阵营涉及这个问题 - 第一个认为终结者是特定于C#的析构函数。所以他们认为这两件事是一样的。

第二阵营认为存在细微差别 - 用维基百科写的 - “术语”析构函数“通常用于表示确定性调用的清理,而”终结器“在垃圾收集器运行时运行。”

但是让我为自己澄清一些事情。确定性地调用清理?在C#规范和msdn中写道,无法调用析构函数(它们是自动调用的)。可以自动调用它们的唯一情况是垃圾收集器。

所以我没有看到确定性调用的清理与垃圾收集器的情况有任何区别。

是这样吗?

6 个答案:

答案 0 :(得分:5)

存在巨大差异。 确定性地调用意味着你知道它什么时候被调用。

在C ++中:

{
    Person a;
    a.Name = "John";
    InvitePerson(a);
} // <-- Destructor is always invoked when the scope is left

在C#中:

{
    Person a = new Person();
    a.Name = "John";
    InvitePerson(a);
} // <-- The finalizer is NOT invoked when the scope is left

指出,主要区别在于:
在C#和其他垃圾收集语言中,您不知道何时,甚至如果将执行终结器。
但是,在C ++中,一旦对象超出范围,就会知道何时 执行析构函数。

答案 1 :(得分:3)

官方立场是C#具有析构函数(~ClassName() {})并且它们映射到System.Object.Finalize()。在VB.NET中,你只需像ToString一样覆盖Finalize。

但是,有一些困惑,你是对的。但它更多的是Finalize / Destructor vs Dispose。这是a post from Eric Lippert(指维基百科):

  

是的,通过这些定义,C#规范   弄错了。我们称之为   规范中的“析构函数”实际上是一个   终结者,我们称之为   由a调用的“Dispose()”方法   “使用”声明实际上是一个   “析构函数”。

答案 2 :(得分:1)

在C#中,finalizer和析构函数是同一个东西的不同名称。

C#语言规范(1.6.7.6)实际上将这些称为Destructors。但是,由于名称析构函数可能很容易被误认为是C ++对应物(这与C#中的析构函数完全不同),因此使用术语终结器是有意义的。

答案 3 :(得分:1)

第二种观点更为正确。您无法确保对象的析构函数将在指定时间运行。所以它不是像C ++那样的descructor,你可以在其中显式调用delete obj。 在.Net中,对于需要在使用后清理一些资源的对象,您应该实现IDisposable并在完成对象时显式调用Dispose,或者使用using()

答案 4 :(得分:0)

确定性意味着您可以在任何给定时间释放内存。这在C#中是不可能的,因为GC会在无限期的时间点通过终结器线程调用析构函数。

答案 5 :(得分:0)

我认为这只是一个不同术语的案例。在不同的文本中不同地定义/使用单词 - 一直发生。

但是,如果您依赖垃圾收集器,则没有“确定性调用的清理”。你的结论是:

  

所以我没有看到确定性调用的清理与垃圾收集器的情况有任何区别。

...在您提供的上下文中没有意义。区别在于一个是确定性调用的,另一个不是。