C# - 如何继承过程中不CLR组织内存/参考?(C# - How does CLR organiz

2019-07-05 04:27发布

假设我有代码段如下:( 澄清目的/未很好地形成 )

class Employee
{
    #region fields

    protected string _empID;

    protected string _empName;

    protected readonly string _ssn;

    #endregion

    public Employee(){}   

    public Employee(string _empID,string _empName,string _ssn)
    {
        this._empID =_empID;
        this._empName=_empName;
        this._ssn = _ssn;
    }
}


class Manager : Employee
{
    private string _branchID;

    public Manager(int  _branchID):base(string _empID,string _empName,string _ssn)
    {
        this._branchID=_branchID;
    }
}

static void Main()
{
   Manager mgr = new Manager("1","sam","xxx","Branch1");
}

使用基本 。

在这种情况下,如何继承的组织? 我有一些坏的假设如下:

作为管理器从雇员衍生Manager类填充有(EMPID,empName,SSN)

-----------------
 Manager
-----------------
empID
empName
ssn
branchID

步骤1:构造调用:基部( “1”, “SAM”, “XXX”)

步骤2:基类(员工)构造填充日提交的派生类(EMPID,empName,SSN)

步骤3:branchID由派生类的构造分配

.......

我的问题是

  • Answer 1:


    (来源: rvenables.com )

    是的,派生类也将包含在内存中的基类的字段。 在通过C#CLR的112页,杰弗里里希特说:

    “然后,M3对其执行代码构造一个管理器对象。这使得管理器类型,一个管理器对象,在托管堆被创建,如图4-9的一个实例。正如你可以看到,该管理器对象-as做所有对象-具有一种类型的对象的指针和同步块的索引。 该对象还包含必要的字节,以容纳所有由管理器类型作为由管理器类型的任何基类定义的任何实例字段定义的实例的数据字段(在这种情况下,员工和对象)“。 (强调)

    另外值得一提的是,存储器的单独的块用于任何类型的基创建。 但只适用于数据类型(所以只有一次,最多)。 当你创建一个Manager对象(从员工派生),CLR将确保有一个管理器类型的对象 ,并在堆上的职业类型的对象

    1)里氏,杰弗里。 通过C#CLR。 雷德蒙:微软出版社,2006。( 亚马逊链接 )



    Answer 2:

    一个对象,具有一个头部,它包括一个指针,指向其实际类型信息开始。 这种类型的信息包括虚函数表的工作,哪些方法实际上意味着什么。 CLR使用的是虚函数表在执行时调用覆盖的方法。

    对象头之后附带所有与该对象相关联的实例数据-包括基础类字段和派生类的字段。 这一切都在一个地方 - 它不喜欢的派生类的实例也有基类的“隐藏”的实例的引用。 我强烈怀疑的基类领域是第一位的,因为那么基类的方法仍然可以通过偏移参考(组装),以相同的字段从对象的“顶部” ......但我没有任何东西我的面前证实了这一点。

    IIRC,杰夫·里希特的“通过C#CLR”谈到这一切在一定的深度-它的信息,这种事情的重要来源。



    Answer 3:

    你能想到的对象为具有“槽”里,你可以把方法和字段...基类必须插槽1,2,3的领域,比方说,一个方法插槽4.如果您创建派生类,新的字段将增加另一个时隙(例如时隙5)。

    通过这种方式,使用基类的类型的变量仍然访问权字段,而无需担心差异。 派生类的构造函数必须首先调用基类的构造函数,即使你没有明确在代码中指定。

    如果你的插槽,4-方法是虚拟的,你的派生类中重写它,你把插槽4中重写方法再次,如果你隐藏它(通过new ),它分配一个新的插槽(因此它只能通过一个变量被称为派生类的)。

    嗯,这是我如何看待它。 的一种简化的方式一种,但它可以帮助。 我想这可能是一个内存块,但话又说回来,这是一个implememtation细节。



    文章来源: C# - How does CLR organize memory/reference during the inheritance?