|
1
1
烟雾和镜子是最好的描述方式。我会尽力的。值类型不支持继承,并且不能有虚拟方法。但是,int类型有ToString()和GetHashCode()方法,这两种方法都是虚方法。它从System.Object继承它们。 这个魔法来自于拳击的转换。有专门的IL操作码来执行, OpCodes.Box 和操作码。将值类型转换为对象,存储原始值类型的值。相反,取消装箱也会将对象转换回值类型。 如果你有一个好的.NET编译器,比如C#编译器,你永远不会自己显式调用转换。编译器可以从语言语法中找出何时需要这种转换,并发出所需的IL代码。 System.Int32类型是一种帮助程序类型,编译器对此有专门的知识。它只对它的方法有用,您从不显式地创建它的实例。当编译器知道您正在调用int“class”的方法时,它会直接调用这些方法。 所有这一切共同创造了int从System.Object(通过System.ValueType)派生的假象。运用“如果它看起来、游泳、嘎嘎叫得像鸭子,那就是鸭子”的原则。 |
|
|
2
1
值类型由各种语言编译器和CLR专门处理。很简单,CLR知道从ValueType派生的所有内容都将由value传递,并且本地ValueType变量存在于堆栈中。 我不知道如果不进入“实现定义”的领域,还能说多少关于值类型的话。 |
|
|
3
1
在这种情况下,类层次结构有点人为。类型是引用还是值类型直接存储在类型元数据中,因此CLR不需要查看它是否派生自System.ValueType。但是System.ValueType确实有帮助—它实现了值相等性检查和GetHashCode()。 CLR在堆栈上为元数据中标记为“.class value”的类型的任何局部变量分配空间。具体何时发生取决于代码是否优化。如果它没有被优化,那么它会发生在声明中以帮助调试。如果它是优化的,那么可能会尽可能晚,但这取决于实现。
|