如果我有两个类,A
和 B
,其中 B 派生自 A:
class A {}
class B : A { }
我可以非常愉快地将 B
的实例向上转换为 A
。
B b = new B();
A a = b;
现在,我可以理解运行时如何确定基础类型是 B,如 ECMA-335 的第 132 页(公共(public)语言基础设施 (CLI) 分区 I 到 VI)状态
Objects of instantiated types shall carry sufficient information to recover at runtime their exact type (including the types and number of their generic arguments). [Rationale: This is required to correctly implement casting and instance-of testing, as well as in reflection capabilities
那么,运行时如何知道虽然底层类型是B
,但它实际上存储在A
中。我知道一个事实,我不会看到 B
上可用的方法,但是如果底层类型是 B
,它如何存储存储位置的类型 A
?
这有意义吗?
最佳答案
对象是一个B,CLI知道它是一个B。知道A的主要是编译器,编译器然后声明field或者local作为 A 类型(或者,在某些情况下,如方法链接,该类型通过方法的返回类型已知,该类型被标记为调用者的 IL)。所以基本上:调用代码本身就是“我认为这是一个 A”。作业等通常都可以提前核实,因此不存在出错的风险。如果您试图破解 IL 以故意将其弄错,则运行时会告诉您关闭并拒绝运行该方法。由于这些原因,将已知为 B 的值分配给 A 本地/字段不需要任何类型检查 - 它只是直接分配。
关于c# - 有关内存中转换的 C# 引用类型的信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13037413/