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

时间:2010-03-05 22:58:10

标签: c# destructor access-modifiers

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

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

我尝试过公共,私有,受保护和内部。没有访问修饰符,它工作正常。由于this article shows〜析构函数基本上是一个受保护的Finalize函数的合成糖,因此我觉得奇怪的是你不能使用至少受保护的析构函数。文章确实说“无法调用析构函数。它们会被自动调用。”这是执行该行为的方式吗?

我最后只是实现了IDisposable,但我很好奇... 还有其他原因导致你无法在析构函数上添加访问修饰符吗?

4 个答案:

答案 0 :(得分:16)

源代码中声明的成员的辅助功能域包含可以访问该成员的程序文本的所有部分的集合。

辅助功能修饰符修改辅助功能域的内容。

关于辅助功能修饰符的一个有趣的事实是,辅助功能修饰符始终使辅助功能域更大或使其保持相同的大小。辅助功能修饰符永远不会使辅助功能域更小

我们希望析构函数的可访问域始终为空。也就是说,永远任何中访问析构函数应该是合法的>程序文本区域。

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

因此,允许用户增加可访问域的大小对我们来说是愚蠢的;我们不想向用户提供一个工具来击败这个经过仔细考虑的语言设计方面。

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

  

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

正确。该规范在10.13节中对此进行了说明。请注意,涉嫌保护的“Finalize”方法的辅助功能域也是空的;它可能既不被覆盖也不被称为。

我们可以选择一些完全不同的机制来实现析构函数,但这就是我们选择的那个。我们碰巧为析构函数选择了一些特定的实现策略这一事实与析构函数的可访问域应该被强制保持为空以保证空的事实没有特别的关系。

答案 1 :(得分:14)

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

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

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

因此,在方法上放置一个access-modifier没有任何意义。无法访问它,并且无法修改该访问。

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

答案 2 :(得分:5)

这是因为,正如您所指出的那样,“无法调用析构函数。它们会被自动调用。”

对无法访问的内容设置访问修饰符毫无意义。

答案 3 :(得分:0)

您应该使用一次性模式。

  

Finalize/Dispose pattern in C#