Che*_*hen 7 .net c# clr il value-type
我想我已经知道了一堂课的答案,只想确认我的理解是正确的.假设我有一个ClassA名为的实例a.何时a.MethodA()被调用:
(1)CLR找到的类型ClassA由所述类型的指针的a在堆(类型已经装载到堆)
(2)MethodA在类型中找到,如果没有找到,则转到它的基类型,直到object上课.
也许我的理解不太准确,但我认为这是基本正确的(纠正我,如果它是错的!).这是一个简单结构的问题.
struct MyStruct
{
public void MethodA() { }
}
Run Code Online (Sandbox Code Playgroud)
我有var x = new MyStruct();,它的值在堆栈上,并且MyStruct已经加载到堆中的类型.执行时x.MethodA(),当然没有拳击.CLR如何找到MethodA并获取IL并执行/ JIT呢?我想答案可能是:(再次,如果我错了,请纠正我)
(1)我们有声明类型的x堆栈上.CLR通过堆栈上的信息找到它的类型,并MethodA在其类型中查找.- 让我们来称呼它assumptionA.
如果你告诉我我assumptionA是对的,我会很高兴的.但即使它是错的,它也说明了一个事实:CLR有一种方法可以在没有装箱的情况下找到结构类型.
现在怎么样x.ToString()还是x.GetType()?我们知道该值将被加框,然后它将像一个类一样执行.但为什么我们需要拳击呢?既然我们可以得到它的类型(假设A告诉我们),为什么不去它的基类型并找到方法(就像一个类)?为什么这里需要昂贵的箱子操作?
假设A是错误的。C# 编译器的符号表存储类型信息。几乎所有情况下都使用静态类型信息,仅在类型检查(is运算符)、强制转换(as运算符和实际强制转换语法)和数组变化期间才需要存储在对象中的动态类型,然后仅当动态类型不是“ t 编译器知道。未装箱结构的动态类型始终是静态已知的,并且类实例的动态类型在实例化附近和执行类型检查的条件块内部是静态已知的(例如,if (x is T) y = (T)x;在 then 部分中已知类型,因此演员不需要另一个动态检查)。
好的,现在因为 C# 编译器静态地知道 的类型x,它可以进行重载解析并找到被调用的确切MethodA。然后它发出 MSIL 以将参数推送到 MSIL 虚拟堆栈上,并发出包含对该特定方法的元数据引用的调用指令。运行时不需要类型检查。
对于x.ToString(),C# 编译器仍然知道它要调用的确切方法。如果ToString已被struct类型覆盖,则它需要一个类型为pointer-to-MyStruct的参数,编译器无需装箱即可处理该参数。如果ToString尚未被覆盖,编译器将生成对 的调用Object.ToString,该调用需要一个对象作为其参数。要将xMSIL 虚拟堆栈作为正确类型推送,需要装箱。
GetType 是一种静态已知类型的特殊情况,编译器不会调用任何方法,它只是从符号表中获取类型信息并将元数据引用直接填充到 MSIL 中。
| 归档时间: |
|
| 查看次数: |
2253 次 |
| 最近记录: |