C# - How does CLR organize memory/reference during

2019-02-11 02:25发布

Suppose i have the code snippet as follows : ( clarification purpose/not well formed)

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");
}

Using base keyword I am invoking parent class constructor .

In this case how the inheritance is organized? I have some bad assumptions as follow:

As Manager is derived from Employee, Manager class is filled with (empID,empName,ssn)

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

step 1 : constructor invoking :base( "1","sam","xxx")

step 2 : base class(Employee) constructor fills the derived class filed (empID,empName,ssn)

step 3 : branchID is assigned by derived class constructor

.......

My question is

  • If a class is derived from base class, the derived class also has the base class' hidden fields?
  • Derived class shares Base class fields? I mean separate memory block is allocated for Base class and derived class?
  • 3条回答
    Deceive 欺骗
    2楼-- · 2019-02-11 02:57

    http://www.rvenables.com/linkjackandsufferaccidentaldroptable/clr_via_csharp_f4.9.png

    Yes, the derived class will also contain the base class fields in memory. On page 112 of CLR via C#, Jeffrey Richter says:

    "Then, M3 executes its code to construct a Manager object. This causes an instance of the Manager type, a Manager object, to be created in the managed heap, as shown in Figure 4-9. As you can see, the Manager object-as do all objects-has a type object pointer and sync block index. This object also contains the bytes necessary to hold all of the instance data fields defined by the Manager type as any instance fields defined by any base classes of the Manager type (in this case, Employee and Object)." (Emphasis Added)

    It's also worth noting that a separate block of memory is created for any base types. But ONLY for the type data (so only once, at most). When you create a Manager object (which derives from Employee), the CLR will ensure that there is a Manager Type Object, and an Employee Type Object on the heap.

    1) Richter, Jeffrey. CLR via C#. Redmond: Microsoft Press, 2006. (Amazon Link)

    查看更多
    The star\"
    3楼-- · 2019-02-11 03:05

    An object starts with a header which includes a pointer to its actual type information. That type information includes the vtable to work out which method actually means what. The CLR uses that vtable at execution time to call overridden methods.

    After the object header comes all the instance data associated with the object - including base class fields and derived class fields. It's all in one place - it's not like the instance of the derived class also has a reference to a "hidden" instance of the base class. I strongly suspect that the base class fields come first, as then methods in the base class can still refer (in assembly) to the same fields via offsets from the "top" of the object... but I don't have anything in front of me to confirm this.

    IIRC, Jeff Richter's "CLR via C#" talks about all of this in some depth - it's a great source of information for this kind of thing.

    查看更多
    小情绪 Triste *
    4楼-- · 2019-02-11 03:07

    You can think of the object as having "slots" where you can put in methods and fields... the base class would have slots 1,2,3 for the fields, and, say, a method has slot 4. If you create a derived class, a new field would add another slot (e.g. slot 5).

    That way, using a variable of the type of the base class still accesses the right fields without having to worry about differences. A constructor of a derived class has to call the base class constructor first, even if you don't explicitly specify it in your code.

    If your slot-4-method is virtual and your derived class overrides it, you put the override method in slot 4 again, if you hide it (via new), it allocates a new slot (so it can only be called via a variable of the derived class).

    Well that's how i think about it. Kind of a simplified way, but it helps. I think it might be one memory block, but then again, that's an implememtation detail.

    查看更多
    登录 后发表回答