为什么C#不允许在析构函数上使用访问修饰符?

Nic*_*sen 3 c# destructor access-modifiers

我正在为一个小项目创建一个简单的类,并决定只为快速impl添加一个析构函数而不是使用IDisposable,每当有一个带有访问修饰符的析构函数时,我就遇到了编译器错误.

public class MyClass
{
    public ~MyClass()
    {
        // clean resources
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过公共,私有,受保护和内部.没有访问修饰符,它工作正常.由于这篇文章显示 ~destructor本质上是一个受保护的Finalize函数的合成糖,因此我觉得奇怪的是你不能在析构函数上使用至少受保护的东西.文章确实说"无法调用析构函数.它们会被自动调用." 这是如何强制执行该行为的?

我最后只是实现IDisposable了,但我很好奇...... 还有其他原因你不能在析构函数上放置访问修饰符吗?

Eri*_*ert 16

在源代码中声明的成员的可访问域域包含可以访问该成员的程序文本的所有部分的集合.

一个可访问性修饰符修改访问域的内容.

关于可访问性修饰符的一个有趣的事实是,可访问性修饰符总是使可访问性域更大或使其保持相同的大小.辅助功能修饰符永远不会使辅助功能域变小.

我们希望析构函数的可访问域始终为空.也就是说,在程序文本的任何区域访问析构函数都不应该是合法的.

这样做的原因是因为我们希望向您提供强制不变量,即在所述生命周期结束时,在对象的生命周期中,特定实例的析构函数只运行一次.(在最终确定期间死亡对象的"复活"会带来有趣的问题,我将在稍后讨论.)通过禁止访问析构函数,我们确保用户代码不会提前调用析构函数.

因此,允许用户增加可访问域的大小对我们来说是愚蠢的; 我们不想向用户提供工具来打败这种经过深思熟虑的语言设计方面.

打败这个安全功能吗?为什么?您能描述一个场景,在这个场景中,您能够从程序文本的某个区域调用析构函数吗?

析构函数基本上是一个受保护的Finalize函数的合成糖

正确.该规范在10.13节中对此进行了说明.请注意,据称受保护的"Finalize"方法的可访问性域也是空的; 它可能既不被覆盖也不被称为.

我们可以选择一些完全不同的机制来实现析构函数,但这就是我们选择的那个.事实上,我们碰巧为析构函数选择了一些特定的实现策略,因为出于安全原因,应该强制执行析构函数的可访问域以保持为空.


abe*_*nky 14

访问修饰符控制用户编写的代码范围可以调用该方法.

public 表示任何用户编写的代码都可以调用方法等等.

但是,析构函数不会被用户编写的代码调用.GC会自动调用析构函数.访问修饰符对GC没有任何意义.

因此,在方法上放置access-modifier没有意义.无法访问它,并且无法修改该访问权限.

你不妨考虑对析构函数的访问是"超级私有",因为没有人,甚至对象本身都不能实际调用析构函数.


Eri*_* J. 5

这是因为,正如你所指出的那样,"无法调用析构函数.它们会被自动调用."

在无法访问的内容上拥有访问修饰符毫无意义.

  • 就像把门把手放在墙上一样. (13认同)