C# Language Specification 3.0的第10.13节“析构函数”声明如下:
析构函数不是继承的。因此,除了可以在该类中声明的类之外,类没有析构函数。
C# Programming Guide的Destructors部分包含一个示例,演示如何调用继承层次结构中的析构函数,包括以下语句:
...自动调用...类的析构函数,按顺序从最派生到最少派生。
我用各种实际例子对此进行了调查,其中包括一个定义析构函数的基类,一个派生类,它继承自基类并且没有定义析构函数。创建派生类的实例,允许对实例的所有引用超出范围,然后强制执行垃圾收集,演示在派生类的实例完成时调用基类中定义的析构函数。
我的问题是“析构函数不被继承”实际意味着什么,因为虽然你不能显式调用析构函数,但是继承链中的析构函数会被自动调用,并且即使派生类也会调用基类析构函数class没有定义析构函数?
是否与垃圾收集器而不是C#语言/编译器实现最终化的一些微妙的语义区别有关?
编辑1:
虽然C#语言规范还声明“实例构造函数不是继承的”,但与构造函数相关的行为与析构函数有很大不同,并且更符合IMO与“未继承”的术语,如下例所示:
public class ConstructorTestBase
{
public ConstructorTestBase(string exampleParam)
{
}
}
public class ConstructorTest: ConstructorTestBase
{
public ConstructorTest(int testParam)
: base(string.Empty)
{
}
}
...
// The following is valid since there is a derived class constructor defined that
// accepts an integer parmameter.
ConstructorTest test1 = new ConstructorTest(5);
// The following is not valid since the base class constructor is not inherited
// by the derived class and the derived class does not define a constructor that
// takes a string parameter.
ConstructorTest test2 = new ConstructorTest("Test");
与析构函数相关的行为与此非常不同,如以下示例所示,该示例通过仅向基类添加析构函数来扩展先前的构造函数示例。
public class ConstructorTestBase
{
public ConstructorTestBase(string exampleParam)
{
}
~ConstructorTestBase()
{
Console.WriteLine("~ConstructorTestBase()");
}
}
...
ConstructorTest test1 = new ConstructorTest(5);
test1 = null;
GC.Collect();
上面的示例演示了在派生类的实例完成时将调用基类构造函数,即使派生类没有显式定义析构函数。
我的观点很简单,我遇到过很多人没有意识到或明白发生这种情况的原因,其中很大一部分原因是“析构函数不是继承的”声明。
编辑2:
C#语言规范还说明了以下内容,并给出了底层实现的代码示例:
通过覆盖System.Object上的虚拟方法Finalize来实现析构函数。 不允许C#程序覆盖此方法或调用它 (或覆盖它)直接。
由于幕后实现实际上是基于继承,如上所述,我认为我的问题是有效的,我认为到目前为止我收到的任何回复都没有解决这个问题正确 - “破坏者不被遗传”实际意味着什么?
答案 0 :(得分:19)