终结器和析构器,维基百科怎么说?

发布于 2024-11-05 04:24:12 字数 290 浏览 5 评论 0 原文

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

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

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

因此,我认为确定性调用的清理与垃圾收集器的情况没有任何区别。

是这样还是不是?

As I understand there are two camps concerning this question - the first one thinks that finalizer is a destructor specific to C#. So they think that these two things are the same.

The second camp thinks that there's a slight difference - written in Wikipedia - "the term “destructor” is typically used to mean a deterministically-invoked cleanup, whereas a “finalizer” runs when the garbage collector says to run it."

But let me clarify something for myself. Deterministically-invoked cleanup? In C# specification and msdn it's written that destructors cannot be invoked(they are invoked automatically). The only case when they may be invoked automatically is by garbage collector.

So I don't see any difference between deterministically-invoked cleanup and the case with the garbage collector.

Is it so or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

々眼睛长脚气 2024-11-12 04:24:12

有很大的不同。 确定性调用意味着您知道它将何时被调用。

在 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++ 中,您确实知道一旦对象超出范围,何时以及就会执行析构函数。

There is a huge difference. Deterministically invoked means you know, when it it will be invoked.

In C++:

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

In C#:

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

As pointed out, the main difference is:
In C# and other garbage collected languages, you don't know when or even if the finalizer will be executed.
In C++ however, you do know when and that the destructor is executed as soon as the object goes out of scope.

白云不回头 2024-11-12 04:24:12

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

虽然有些混乱,但你是对的。但更多的是关于 Finalize/Destructor 与 Dispose。这是Eric Lippert 的帖子(参考维基百科):

是的,根据这些定义,C# 规范
弄错了。我们称之为
规范中的“析构函数”实际上是一个
终结器,以及我们所说的
“Dispose()”方法被调用
“using”语句实际上是一个
“析构函数”。

The official stance is that C# has destructors (~ClassName() {} ) and they map onto System.Object.Finalize(). In VB.NET you just override Finalize much like ToString.

There is some confusion though, you're right about that. But it's more about Finalize/Destructor vs Dispose. Here is a post from Eric Lippert (referring to Wikipedia):

Yes, by these definitions, the C# spec
gets it wrong. What we call a
“destructor” in the spec is actually a
finalizer, and what we call the
“Dispose()” method invoked by a
“using” statement is in fact a
“destructor”.

冷弦 2024-11-12 04:24:12

在 C# 中,终结器和析构器是同一事物的不同名称。

C# 语言规范 (1.6.7.6) 实际上将它们称为析构函数。然而,由于名称析构函数很容易被误认为是 C++ 对应的析构函数(这与 C# 中的析构函数有很大不同),因此使用术语终结器来代替是有意义的。

In C#, finalizer and destructor are different names for the same thing.

The C# language specification (1.6.7.6) actually refers to these as destructors. However, as the name destructor may easily be mistaken for the C++ counterpart (which is quite different from a destructor in C#) it makes sense to use the term finalizer instead.

转身泪倾城 2024-11-12 04:24:12

第二种意见更正确。您无法确保对象的析构函数将在指定时间运行。所以它不是一个析构函数,就像在 C++ 中一样,您可以在其中显式调用delete obj

在 .NET 中,对于需要在使用后清理一些资源的对象,您应该实现 IDisposable 并在使用完该对象或使用 using() 块时显式调用 Dispose。

The second opinion is more correct. You can't ensure that the destructor of an object will be run at a specified time. So it is not a destructor, like in C++, where you can explicit call delete obj.

In .NET, for objects that need to clean up some resources after usage, you should implement IDisposable and call Dispose explicitly when you are finished with the object, or with a using() block.

彼岸花ソ最美的依靠 2024-11-12 04:24:12

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

Deterministically means that you can release the memory at any given time. This is not possible in C# since the destructor is invoked by the GC through the finalizer thread at an indefinite point in time.

残龙傲雪 2024-11-12 04:24:12

我认为这只是术语不同的情况。在不同的文本中,单词的定义/使用不同——这种情况经常发生。

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

因此,我认为确定性调用的清理与垃圾收集器的情况之间没有任何区别。

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

I think this is just a case of differing terminology. Words are defined/used differently in different texts - happens all the time.

However there is no "deterministically invoked cleanup" if you are relying on the garbage collector. Your conclusion:

So I don't see any difference between deterministically-invoked cleanup and the case with the garbage collector.

... doesn't make sense in the context you give it. The difference is that one is deterministically invoked, and the other is not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文