【发布时间】:2010-11-08 12:43:25
【问题描述】:
今天早上我的大脑出现了段错误,试图准确了解 C# 如何以及何时可以从对该对象的引用中计算出对象的类型。考虑以下高度非原创的示例代码:
class Foo { public virtual void Baz() { } }
class Bar : Foo { }
class Program {
static void Main() {
Foo f = new Bar();
f.Baz();
}
}
那里的引用类型是Foo,但实际创建的对象实例是Bar。该 Bar 实例有一些开销,即同步块索引和对 MethodTable 的引用,大概是 Bar 的 MethodTable。如果您查看堆上的 Bar 对象,唯一的类型线索就是 MethodTable 引用,这表明它是 Bar。
那么问题来了。 C# 有什么方法可以从实际的对象图中知道“f”是 Foo,如果是,怎么做?引用“f”本身是否包含类型信息?当我调用 f.Baz() 时,我是否认为调度是通过 Bar 的 MethodTable 发生的?仅仅是C#编译器使用流分析来弄清楚发生了什么并防止任何非法操作的情况吗?当 Foo 被翻译成 IL 时,CLR 是否真的不关心 Foo 的类型声明?
抱歉,如果这是一个冗长且措辞不佳的问题 - 如果需要任何澄清,请告诉我!
TL;DR - CLR 中的多态引用如何工作?实际与声明的类类型之间的差异是如何持续存在的,您能从结果 IL 中分辨出原始声明是什么吗?
【问题讨论】: