ValueType.GetType() 如何确定结构的类型? [英] How is ValueType.GetType() able to determine the type of the struct?

查看:17
本文介绍了ValueType.GetType() 如何确定结构的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一个引用类型,对象的内存布局是

For a reference type, the object's memory layout is

| Type Object pointer|
|    Sync Block      |
|  Instance fields...|

对于一个值类型,对象布局好像是

For a value type, the object layout seems to be

|  Instance fields...|

对于引用类型,GetType 表示从类型对象指针"中查找对象.给定引用类型对象的所有对象都指向同一个类型对象(也有方法表)

For a reference type, GetType means find the object from the 'Type Object pointer'. All objects of a given reference type object point to the same type object (which also has the method table)

对于值类型,此指针不可用.那么 GetType() 是如何工作的呢?

For a value type, this pointer isn't available. So how does GetType() work ?

我用谷歌查了一下,我发现了这个片段……有点模糊.有人能详细说明一下吗?

I checked with Google and I found this snippet.. which is a bit hazy. Can someone elaborate?

解决办法是在存储的值只能存储某种类型的值.这是由验证者保证.来源

The solution is that the location in which a value is stored may only store values of a certain type. This is guaranteed by the verifier. Source

推荐答案

在值类型框上调用 GetType() 值类型.通过将值类型移到堆上,您现在有了一个引用类型,它现在有一个指向该对象类型的指针.

Calling GetType() on a value type boxes that value type. By moving the value type onto the heap you now have a reference type which now has a pointer to the type of that object.

如果你想避免拳击,你可以调用 GetTypeCode 返回一个枚举,指示值类型的类型,而不对其进行装箱.

If you wish to avoid boxing you can call GetTypeCode which returns an enumeration that indicates the type of the value type without boxing it.

这是一个显示发生的拳击的例子:

Here is an example showing the boxing that takes place:

C#:

class Program
{
    static void Main()
    {
        34.GetType();
    }
}

Main() 的 IL:

IL for 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 
}

<小时>

为了显示编译器在做什么,让我们像这样改变文字的类型:


To show what the compiler is doing, lets change the type of the literal like this:

class Program
{
    static void Main()
    {
        34L.GetType();
    }
}

通过在文字后添加 "L",我告诉编译器我希望将此文字转换为 System.Int64.编译器看到这一点,当它发出 box 指令时,它看起来像这样:

By adding the "L" after the literal I am telling the compiler that I want this literal to be converted to a System.Int64. The compiler sees this and when it emits the box instruction it looks like this:

.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 
}

如您所见,编译器已经完成了确定要发出的正确指令的艰巨工作,之后就由 CLR 来执行它们.

As you can see, the compiler has done the hard work of determining the correct instructions to emit, after that it is up to the CLR to execute them.

这篇关于ValueType.GetType() 如何确定结构的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆