今天早上我脑子短路了,试图理解C#如何以及何时可以通过对对象的引用来确定对象的类型。考虑以下非常不原创的示例代码:
class Foo { public virtual void Baz() { } }
class Bar : Foo { }
class Program {
static void Main() {
Foo f = new Bar();
f.Baz();
}
}
引用类型是Foo,但实际创建的对象实例是Bar。该Bar实例有一些开销,例如同步块索引和对一个方法表的引用,可能是Bar的方法表。如果您查看堆上的Bar对象,其类型的唯一线索是方法表引用,这表明它是一个Bar。
那么问题来了。C#有没有办法从实际对象图中知道"f"是Foo,如果有,如何知道?参考"f"本身是否包含类型信息?当我调用f.Baz()时,我想知道分派是否仍然通过Bar的方法表进行?C#编译器是否仅使用流分析来解决正在发生的事情并防止任何非法操作?当Foo声明被翻译成IL后,CLR实际上不再关心吗?
如果这是一个冗长且措辞不佳的问题,请原谅 - 让我知道是否需要任何澄清!
TL;DR- CLR中多态引用是如何工作的?实际与声明的类类型之间的差异如何持久化,并且能否从生成的IL中推断出原始声明是什么?