c# - C# 中的继承和析构函数

标签 c# inheritance destructor

根据 this ,它声明 析构函数不能被继承或重载。 在我的例子中,对于所有子类,析构函数将是相同的。这几乎是在告诉我必须在每个子类中定义相同的析构函数吗?我无法在基类中声明析构函数并处理销毁?假设我有这样的东西:

class A
{
    ~A()
    {
        SomethingA();
    }

}

class B : A
{

}

B b = new B();

B被销毁时,它的析构函数不会被调用吗?

最佳答案

According to this, it states that Destructors cannot be inherited or overloaded.

正确。析构函数不是可继承的成员,也不是虚拟的,因此不能被覆盖。它们始终具有相同的签名,因此它们不会过载。

In my case, for all subclasses, the destructors will be identical.

你问这样一个基本问题的事实告诉我,你不应该首先实现析构函数。正确实现析构函数是 C# 中最难做的事情之一在除最微不足道的情况外的所有情况下。为什么您认为需要实现析构函数?

Is this pretty much telling me that I must define the same destructor in each sub class?

不,一点也不。您是如何从析构函数不是继承的这一事实得出这个结论的?

There is no way that I can declare the destructor in the base class and have the handle the destruction?

当然,这是一个明智的做法,前提是您一开始就决心实现析构函数。

When B is destroyed, its destructor won't be called?

这是不正确的。

我突然想到,与在这里提出问题并等待答复相比,您自己尝试花费的时间要少得多。

When does the destructors actually get called? Is it on garbage collection, when the variable falls out of scope?

我之前的猜想是正确的。 在深入了解整个垃圾收集过程之前,绝对不应该实现析构函数。例如,您认为变量在超出范围时会被收集这一事实表明您并不这样认为深入理解这一点以编写正确的析构函数。

当一个对象被收集器确定为无法从 gc root 访问时,并且该对象具有未被抑制的终结器,则该对象被提升到下一代,方法是将其放置在终结队列中以供 gc 服务终结器线程。如果不是,则回收其内存。

当终结器线程开始运行时,它会运行对象的所有析构函数。 (析构函数将按从派生程度最高到派生程度最低的顺序运行。)在该过程之后,对象可能无法访问也可能无法访问,并且终结可能会或可能不会被抑制。如果确定对象不可达,则整个过程重新开始。

要正确执行此操作,您需要对 GC 过程有多么深入的了解,我怎么强调都不为过。当您编写析构函数时,它会在没有任何意义的环境中运行。对象中的所有引用都可能指向仅以终结器队列为根的对象;通常所有的引用文献都是关于生物的。引用可能指向已经完成的对象。析构函数在不同的线程上运行。即使构造函数失败,析构函数也会运行,因此对象甚至可能无法正确构造非原子值类型的字段可能只被部分写入——当线程中止时,double 字段完全有可能只有四个字节由构造函数设置;终结器将看到部分写入的字段。即使对象被中止的事务置于不一致状态,析构函数也会运行。等等。编写析构函数时,您必须极度防御

这个答案也可能有帮助:

When should I create a destructor?

关于c# - C# 中的继承和析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8174347/

相关文章:

c++ - 为什么不能从析构函数中抛出异常但可以从复制构造函数中抛出异常?

c# - 给定定义为父类的对象列表,有什么方法可以从子类访问变量?

c++ - 如果函数提前返回或抛出异常,是否会调用对象的析构函数?

java - 如何从整个内存中删除()和setUp()?

c# - 日期验证器/格式

c# - .NET 继承 : suppress a property from the base class

c++ - 如何解决,在使用元编程的条件基类的情况下没有成员函数 "print"

c# - 更改新创建对象的保护级别?

c# - DirectShow 将 sampleGrabber 转换为 ISampleGrabber

c# - CRM 将电话调用事件转移到新实体,并在两个实体上显示