C#-什么是;析构函数不是继承的;实际上是什么意思?

C#-什么是;析构函数不是继承的;实际上是什么意思?,c#,.net,idisposable,destructor,finalization,C#,.net,Idisposable,Destructor,Finalization,第10.13节“析构函数”规定如下: 析构函数不是继承的。因此,一个类除了可以在该类中声明的析构函数外,没有其他析构函数 的析构函数部分包含一个示例,演示如何调用继承层次结构中的析构函数,包括以下语句: …用于。。。类被自动调用,并按顺序从最派生到最派生 我已经用各种实际例子对此进行了研究,包括一个定义析构函数的基类,一个从基类继承而不定义析构函数的派生类。创建派生类的实例,允许对该实例的所有引用超出范围,然后强制执行垃圾收集,这表明在派生类的实例最终确定时调用基类中定义的析构函数 我的问题是“

第10.13节“析构函数”规定如下:

析构函数不是继承的。因此,一个类除了可以在该类中声明的析构函数外,没有其他析构函数

的析构函数部分包含一个示例,演示如何调用继承层次结构中的析构函数,包括以下语句:

…用于。。。类被自动调用,并按顺序从最派生到最派生

我已经用各种实际例子对此进行了研究,包括一个定义析构函数的基类,一个从基类继承而不定义析构函数的派生类。创建派生类的实例,允许对该实例的所有引用超出范围,然后强制执行垃圾收集,这表明在派生类的实例最终确定时调用基类中定义的析构函数

我的问题是“析构函数不是继承的”实际上意味着什么,因为尽管不能显式调用析构函数,但继承链中的析构函数会自动调用,基类析构函数也会被调用,即使派生类没有定义析构函数?

终结是由垃圾收集器而不是C语言/编译器实现的,这是否与一些微妙的语义区别有关

编辑1:

虽然C#语言规范还规定“实例构造函数不是继承的”,但与构造函数相关的行为与Destructor明显不同,并且更符合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#程序重写或调用此方法 (或其替代)直接

由于幕后实现实际上是基于继承的,如上所述,我认为我的问题是正确的,我认为迄今为止收到的任何答复都没有正确地解决这个问题——“析构函数不是继承的”到底意味着什么?

这不是一个获胜的问题。我尽我最大的努力去理解你的问题,但你似乎全神贯注于保护自己不受完全虚构的攻击

撇开这一点不谈,一次一个地考虑你的问题:

我的问题是什么是“析构函数” 不是继承"实际上是指,, 虽然你不能打电话 显式析构函数,在 继承链称为 自动地,和基类 即使 派生类不定义 析构函数

它实际上意味着基类的析构函数不是派生类的成员

我的反问题是:“为什么您认为(1)您不能直接调用析构函数,(2)继承链中的析构函数在收集时会自动调用,以及(3)即使派生类没有定义构造函数,基类析构函数也会被调用,这与基类的析构函数是否是派生类的成员有任何关系

它和一些微妙的语义有关吗 最后定稿是什么 由垃圾收集器实现 而不是C语言/编译器

没有

C语言是一种规范;它什么也不实现。C编译器实现规范;它当然不“实现终结”。CLR是实现终结的

不管怎样,基类中的析构函数不是派生类的成员这一事实与CLR垃圾收集器如何实现终结无关

最后,我们将回到CLR终结语义的问题,以及为什么它们与继承问题无关

而C语言规范也规定 “实例构造函数不是 继承的行为 对建设者来说是非常重要的 与拆卸器不同,并且适合 “非继承性”更好 术语

好吧,我接受你的看法。为什么你认为这些行为与继承问题有关?我一点也不明白你为什么相信。与继承有关的是,所讨论的实体是否仅仅因为是基类型的成员而成为派生类型的成员

我同意这样一个事实,即基类型的构造函数不能通过缺少该构造函数的派生类型的构造直接调用,这与构造函数不是继承的事实是一致的。我只是不明白这与析构函数是否被继承的问题有什么关系

更密切的事实是,当使用默认构造函数构造缺少公共无参数构造函数的派生类时,具有公共无参数构造函数的基类确实调用了该构造函数