据我了解,关于这个问题有两个阵营 - 第一个阵营认为终结器是 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?
发布评论
评论(6)
有很大的不同。 确定性调用意味着您知道它将何时被调用。
在 C++ 中:
在 C# 中:
正如所指出的,主要区别是:
在 C# 和其他垃圾收集语言中,您不知道何时甚至是否执行终结器。
然而,在 C++ 中,您确实知道一旦对象超出范围,何时以及就会执行析构函数。
There is a huge difference. Deterministically invoked means you know, when it it will be invoked.
In C++:
In C#:
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.
官方立场是 C# 有析构函数 (
~ClassName() {}
),并且它们映射到System.Object.Finalize()
。在 VB.NET 中,您只需重写 Finalize,就像 ToString 一样。虽然有些混乱,但你是对的。但更多的是关于 Finalize/Destructor 与 Dispose。这是Eric Lippert 的帖子(参考维基百科):
The official stance is that C# has destructors (
~ClassName() {}
) and they map ontoSystem.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):
在 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.
第二种意见更正确。您无法确保对象的析构函数将在指定时间运行。所以它不是一个析构函数,就像在 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.确定性意味着您可以在任何给定时间释放内存。这在 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.
我认为这只是术语不同的情况。在不同的文本中,单词的定义/使用不同——这种情况经常发生。
但是,如果您依赖垃圾收集器,则不存在“确定性调用的清理”。你的结论:
...在您给出的上下文中没有意义。区别在于,一个是确定性调用的,而另一个则不是。
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:
... doesn't make sense in the context you give it. The difference is that one is deterministically invoked, and the other is not.