Finalizers and destructors, what's Wikipedia s

2019-07-17 06:13发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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”.



回答4:

The second opinion is more correct. You can't ensure that destructor of object will be run at specified time. So it is not a descructor, 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 finished with the object, or with using() block



回答5:

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.



回答6:

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.