C# 垃圾收集如何收集具有继承性的对象

C# 垃圾收集如何收集具有继承性的对象,c#,.net,C#,.net,考虑以下代码: class Base { } class Derived : Base { // some code } 如果我们这样做的话,从main开始 Derived d = new Derived(); 我有两个问题: Q1我们知道什么时候做new-Derived()CLR在堆中分配一个派生的对象。但是由于Derived从Base派生,Derived隐式构造函数也调用Base的隐式构造函数,这是否意味着堆中也分配了Base对象 Q2-(如果Q1的答案为真)在GC的上下文中,我们将所有

考虑以下代码:

class Base
{
}
class Derived : Base
{
// some code
}
如果我们这样做的话,从main开始

Derived d = new Derived();
我有两个问题:

Q1我们知道什么时候做
new-Derived()
CLR在堆中分配一个
派生的
对象。但是由于
Derived
从Base派生,
Derived
隐式构造函数也调用
Base
的隐式构造函数,这是否意味着堆中也分配了
Base
对象


Q2-(如果Q1的答案为真)在GC的上下文中,我们将所有引用类型变量都称为根。例如,变量
d
是一个根,这个根只指向
派生的
对象。这里有一个问题,对于
Base
对象没有根变量,理论上
Base
对象总是被垃圾收集器标记为不可访问,然后被清除。这显然是不正确的,那么这是否意味着隐式根变量将分配给
Base
对象以保持其可访问性?

您误解了继承的本质。这里只创建了一个对象,即
派生的
类型的对象。继承意味着派生获得了从Base继承的一些属性,但这并不意味着创建了另一个Base类型的对象。所以对于Q1,答案是否定的。因此没有必要回答Q2。GC有一个要跟踪的内存分配,即派生的。

当您创建派生对象的新实例(例如,
Derived=new-Derived();
)时,将为派生类及其基类分配一个单独的对象,而不是单独的对象。

想象它们都是结构,您必须手动组合派生对象。你可能会得到这样的结果

公共结构库{
...
}
公共结构派生{
公共基地;
...
}
Base所需的内存包含在派生的内存占用空间中