System.Int32包含...另一个System.Int32 [英] System.Int32 contains... another System.Int32

查看:52
本文介绍了System.Int32包含...另一个System.Int32的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用反射检查了 System.Int32 的内容,发现它包含另一个 System.Int32 .

I used reflection to inspect the contents of System.Int32 and found that it contains another System.Int32.

System.Int32 m_value;

我不知道怎么可能.

int 确实是您拥有的整数:如果您将 int 装箱并使用反射更改其 m_value的值字段,您可以有效地更改整数的值:

This int really is the "backing integer" of the one you have: if you box an int and use reflection to change the value of its m_value field, you effectively change the value of the integer:

object testInt = 4;
Console.WriteLine(testInt); // yields 4

typeof(System.Int32)
    .GetField("m_value", BindingFlags.NonPublic | BindingFlags.Instance)
    .SetValue(testInt, 5);
Console.WriteLine(testInt); // yields 5

这种奇异性背后必须有一个合理的解释.值类型如何包含自身?CLR使用什么魔法使它起作用?

There's gotta be a rational explanation behind this singularity. How can a value type contain itself? What magic does the CLR use to make it work?

推荐答案

如上所述,一个32位整数可以存在两个变体中.快速版本,在内存或CPU寄存器(不仅仅是堆栈)中任何地方的四个字节.它可以嵌入到盒装版本的System.Object中.System.Int32的声明与后者兼容.装箱时,它具有典型的对象标头,后跟4个字节来存储值.而这4个字节恰好映射到m_value成员.也许您会明白为什么这里没有冲突:m_value总是 快速的非盒装版本.因为没有盒装盒装整数这样的东西.

As noted, a 32-bit integer can exist in two varieties. Four bytes anywhere in memory or a CPU register (not just the stack), the fast version. And it can be embedded in System.Object, the boxed version. The declaration for System.Int32 is compatible with the latter. When boxed, it has the typical object header, followed by 4 bytes that stores the value. And those 4 bytes map exactly to the m_value member. Maybe you see why there's no conflict here: m_value is always the fast, non-boxed version. Because there is no such thing as a boxed boxed integer.

语言编译器和JIT编译器都敏锐地意识到Int32的属性.编译器负责确定何时需要对整数进行装箱和拆箱,并生成相应的IL指令来执行此操作.并且它知道哪些IL指令可用,从而可以在不先装箱的情况下对整数进行运算.从System.Int32实现的方法可以很容易地看出,例如,它没有对operator ==()的覆盖.这是由CEQ操作码完成的.但是它确实具有Equals()的重写,装箱整数时必须重写Object.Equals()方法.您的编译器需要具有相同的意识.

Both the language compiler and the JIT compiler are keenly aware of the properties of an Int32. The compiler is responsible for deciding when the integer needs to be boxed and unboxed, it generates the corresponding IL instructions to do so. And it knows what IL instructions are available that allows the integer to be operated on without boxing it first. Readily evident from the methods implemented by System.Int32, it doesn't have an override for operator==() for example. That's done by the CEQ opcode. But it does have an override for Equals(), required to override the Object.Equals() method when the integer is boxed. Your compiler needs to have that same kind of awareness.

这篇关于System.Int32包含...另一个System.Int32的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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