对于引用类型,对象的内存布局是
| Type Object pointer|
| Sync Block |
| Instance fields...|
Run Code Online (Sandbox Code Playgroud)
对于值类型,对象布局似乎是
| Instance fields...|
Run Code Online (Sandbox Code Playgroud)
对于引用类型,GetType表示从"类型对象指针"中查找对象.给定引用类型对象的所有对象都指向同一类型对象(也有方法表)
对于值类型,此指针不可用.那么GetType()如何工作?
我查了一下谷歌,我发现了这个片段..这有点模糊.有人可以详细说明吗?
解决方案是存储值的位置可以仅存储特定类型的值.这由验证者保证. 资源
And*_*are 25
调用GetType()值类型的值类型框.通过将值类型移动到堆上,您现在拥有一个引用类型,该类型现在具有指向该对象类型的指针.
如果你想避免装箱,你可以调用GetTypeCode哪个返回一个枚举,指示值类型的类型而不用装箱.
这是一个显示拳击发生的例子:
C#:
class Program
{
static void Main()
{
34.GetType();
}
}
Run Code Online (Sandbox Code Playgroud)
IL代表Main():
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 8
L_0000: ldc.i4.s 0x22
L_0002: box int32
L_0007: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_000c: pop
L_000d: ret
}
Run Code Online (Sandbox Code Playgroud)
编辑:要显示编译器正在做什么,让我们改变文字的类型,如下所示:
class Program
{
static void Main()
{
34L.GetType();
}
}
Run Code Online (Sandbox Code Playgroud)
通过"L"在文字后面添加我告诉编译器我希望将这个文字转换为System.Int64.编译器会看到这个,当它发出box指令时,它看起来像这样:
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 8
L_0000: ldc.i4.s 0x22
L_0002: conv.i8
L_0003: box int64
L_0008: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_000d: pop
L_000e: ret
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,编译器已经完成了确定要发出的正确指令的艰苦工作,之后由CLR来执行它们.
也许Andrew H.认为这很明显,并努力让我理解+1.我的灯泡时刻再次来自Jon Skeet ..这次是通过他的书,我碰巧正在阅读......以及答案所在的确切区域.
考虑下面的代码段.虽然变量类型是BaseRefType,但它指向更专用类型的对象.对于值类型,由于继承是非法的,因此变量类型是对象的类型.
BaseRefType r = new DerivedRefType();
ValueType v = new ValueType();
Run Code Online (Sandbox Code Playgroud)
我失踪的是子弹#1.
<Snipped after J.Skeet's comment since it seems to be wrong>.似乎有一些神奇的东西可以让编译器/运行时知道给定任意变量的'变量类型'.因此运行时以某种方式知道ob是MyStruct类型,即使VT对象本身没有类型信息.
MyStruct ob = new MyStruct();
ob.WhoAmI(); // no box ; defined in MyStruct
Console.WriteLine(ob.GetHashCode()); // no box ; overridden in ValueType
Console.WriteLine( ob.GetType() ); // box ; implemented in Object
Run Code Online (Sandbox Code Playgroud)
因此,我能够调用MyStruct(和ValueType中出于某种原因)定义的方法,而无需装入RefType.
| 归档时间: |
|
| 查看次数: |
4898 次 |
| 最近记录: |