5

我正在为一个小项目制作一个简单的类,并决定只为快速 impl 添加一个析构函数而不是 using IDisposable,每当有一个带有访问修饰符的析构函数时,我都会遇到编译器错误。

public class MyClass
{
    public ~MyClass()
    {
        // clean resources
    }
}

我尝试了公共的、私有的、受保护的和内部的。它在没有访问修饰符的情况下运行良好。因为这篇文章表明~destructor 本质上是受保护的 Finalize 函数的语法糖,所以你不能在析构函数上使用至少 protected 让我感到奇怪。文章确实说“无法调用析构函数。它们会被自动调用。” 这是执行该行为的方式吗?

无论如何我最终只是实现IDisposable了,但我很好奇......还有其他原因为什么你不能将访问修饰符放在析构函数上

4

4 回答 4

18

The accessibility domain of a member declared in source code consists of the set of all sections of program text in which that member may be accessed.

An accessibility modifier modifies the contents of the accessibility domain.

An interesting fact about accessibility modifiers is that an accessibility modifier always makes the accessibility domain larger or keeps it the same size. An accessibility modifier never makes the accessibility domain smaller.

We desire that the accessibility domain of a destructor be always empty. That is, it should never be legal to access a destructor in any region of program text.

The reason for this is because we wish to provide to you the enforced invariant that a destructor for a particular instance is run exactly once in the lifetime of the object, at the end of said lifetime. ("Resurrection" of dead objects during finalization brings up interesting issues which I will discuss at a later date.) By disallowing access to the destructor we ensure that user code never calls a destructor early.

Therefore it would be foolish of us to allow the user to increase the size of the accessibility domain; we do not want to hand the user a tool to defeat this carefully-considered aspect of the design of the language.

Did you want to defeat this safety feature? Why? Can you describe a scenario in which it is important that you be able to call a destructor from some region of program text?

the destructor is essentially syntatic sugar for a protected Finalize function

Correct. The specification notes this in section 10.13. And note that the accessibility domain of the allegedly protected "Finalize" method is also empty; it may be neither overridden nor called.

We could have chosen some completely different mechanism to implement destructors, but that's the one we chose. The fact that we happened to choose some particular implementation strategy for the destructor feature has no particular bearing on the fact that the accessibility domain of a destructor should be enforced to remain empty for safety reasons.

于 2010-03-06T00:07:42.083 回答
16

An access modifier controls which scope of user-written-code can call the method.

public means any user-written-code can call the method, etc, etc.

However, destructors are not called by user-written-code. Destructors are called automatically by the GC. An access modifier means nothing to the GC.

Hence, putting an access-modifier on the method has no meaning. It cannot be accessed, and that access cannot be modified.

You might as well consider the access to a destructor to be "super-private", in that no one, not even the object itself, can actually call the destructor.

于 2010-03-05T23:02:47.810 回答
6

It's because, as you point out, "Destructors cannot be called. They are invoked automatically."

Having an access modifier on something that cannot be accessed is pointless.

于 2010-03-05T23:02:31.523 回答
0

您应该使用一次性模式。

在 C# 中完成/处理模式

于 2010-03-06T01:50:02.507 回答