有关内存中Caste C#引用类型的信息

时间:2012-10-23 19:05:02

标签: c# memory casting polymorphism clr

如果我有两个班级,AB,其中B派生自A:

class A {}
class B : A { }

我可以非常高兴地将B的实例转发给A

B b = new B();
A a = b;

现在,我可以理解运行时如何确定底层类型是B,如ECMA-335(公共语言基础结构(CLI)分区I到VI)的第132页所述

  

实例化类型的对象应携带足够的信息   在运行时恢复它们的确切类型(包括类型和数量)   他们的通用论点)。 [理由:这是正确的   实现铸造和测试实例,以及反思   功能

那么,运行时如何知道虽然底层类型是B,但它实际上存储在A中。我知道我不会在B上看到可用的方法,但如果基础类型是B,它如何存储存储位置的类型A?< / p>

这有意义吗?

2 个答案:

答案 0 :(得分:7)

对象是B,CLI知道它是B.知道A的东西主要是编译器,然后声明字段 local 作为类型A(或者,在某些情况下,类似于方法链接,类型通过方法的返回类型已知,该方法被刻印到调用者的 IL中)。所以基本上:调用代码本身就是“我认为这是一个A”。作业等通常都是事先可以验证的,所以不存在弄错的风险。如果你试图破解IL故意弄错,运行时会告诉你并拒绝运行该方法。由于这些原因,将已知的B值分配给A本地/字段不需要任何类型检查 - 它只是一个直接分配。

答案 1 :(得分:3)

对象的实际类型始终与对象本身一起存储在堆上。指向该对象的引用可以是不同的类型,只要该类型可以从实际类型(例如,基类或该类型的已实现接口)分配。

堆上的每个对象都存储着少量数据 - 该对象的类型就是其中之一。