我想了解如何CLR调度方法调用正确当对象隐藏基类成员对象时参考存储在一个基类变量。
我的混乱的点是由运行时创建目标首标。 上堆对象标题有两个字段:类型指针和同步块索引。 类型指针指向类的方法表中。 即使对象引用是基类的,在堆创建该对象是派生的类的。 这应导致运行时使用派生类对象的方法表。 但运行时正确调用基类成员。
你能帮我理解作为流动如何正确CLR调用方法,在这种情况下?
我想了解如何CLR调度方法调用正确当对象隐藏基类成员对象时参考存储在一个基类变量。
我的混乱的点是由运行时创建目标首标。 上堆对象标题有两个字段:类型指针和同步块索引。 类型指针指向类的方法表中。 即使对象引用是基类的,在堆创建该对象是派生的类的。 这应导致运行时使用派生类对象的方法表。 但运行时正确调用基类成员。
你能帮我理解作为流动如何正确CLR调用方法,在这种情况下?
记录在对象头的对象类型并不重要这里。 编译器发出的方法调用命名的具体类,其方法应被调用。 在所生成的IL相当明显。 例如:
class Base {
void foo() { }
void callFoo() {
foo(); // <== here
}
}
class Derived : Base {
new void foo() { }
}
指示的语句就会产生这种IL:
IL_0002: call instance void ConsoleApplication1.Base::foo()
注基地呼叫操作码的存在,没有歧义。
调用不是虚拟的或以任何方式重写无关与方法表的方法。 C#编译器调用的名称的方法(组装真正含有的字符串名字!)和JIT硬编码的功能分为发射x86代码的地址。 地址不依赖于运行时类型的this
对象引用。