2009-12-21 40 views
5

有点学术问题,但是:价值类型如何像Int实际上工作Value类型如何在.net中工作?

我在mscorlib上使用了Reflector来了解System.Int32是如何实现的,它只是一个从System.ValueType继承的Struct。我正在寻找一个位数组中的值来保存值,但我只找到一个声明为int的字段 - 这意味着它是一个循环引用?

我的意思是,我可以写“int i = 14;”,但数字14需要以某种方式存储在某处,但我无法找到“32位数组”或指针或其他东西。

这是编译器所做的一些神奇的事情吗?这些神奇的类型是规范的一部分吗? (类似于System.Attribute或System.Exception如何是“特殊”类型)

编辑:如果我声明我自己的结构,我向它添加字段。这些字段是内置类型的,例如int。所以CLR知道我拥有一个int。但是它是如何知道int是32位的?这只是说明规范指定了某些基本类型,因此使它们变得“神奇”,还是存在技术机制?假设的例子:如果我想要声明一个Int36,这是一个36位的整数,我可以创建一个类似于Int32的,正如,除了4个额外的位之外,通过指定“好吧,搁置36比特“,还是内置的原语设置石头,我不得不以某种方式解决这个问题(即通过使用Int64和代码,只设置最后36位)?

正如所说,所有非常学术和假设的,但我总是想知道这一点。

+0

其实很好的问题,我想知道自己的魔法是什么。 – Pierreten

+0

我也是,我期待这个问题是关于价值类型如何工作,即堆栈和堆分配等,但我对此自我感到好奇。 – Davy8

+1

重新编辑:据我所知,如果你想创建一个Int36,你将不得不以某种方式在C#或IL中指定它,这将迫使你使用Int32 + Int8或Int64以及最后的28个位被忽略或者其他。将Int36添加到原始底层虚拟机并让它理解位级表示的唯一方法是实现您自己的CLR a la Mono或Rotor。 – itowlson

回答

3

某些基本类型(如整数)是CLI规范的一部分。例如,有些特定的IL指令(如ldc.i4)用于加载这些类型的值,IL指令(如add)具有这些类型的特定知识。 (你的int i = 14例如将被编译到ldc.i4 14,与14内部表示为编译MSIL内的操作码的一部分。)

欲了解更多信息,请参阅CLI spec,第7.2节的分区IIA,“内建类型“。 (无法找到特定部分的链接,对不起。)内置类型为:bool,char,object,string,float32,float64,int [8 | 16 | 32 | 64],unsigned int [8 | 1632 | 64],本地int(IntPtr),本机无符号整数和typedref。该规范指出,他们“在基类库中定义了相应的值类型”,这使我认为Int32实际上是一种围绕“真实”的int32的元数据封装,它在VES级别上生存。

其他值类型,如System.Decimal,System.Drawing.Point或您在自己的代码中定义的任何结构都是不可思议的。

+0

谢谢。因此,在我的假设的Int36示例中,除了使用内置类型(即Int64或bool [36])并且手动对其余类型进行编码之外,我没有别的选择了吗? –

+0

正确。请参阅关于您的问题的“重新编辑”评论。除非您实施自己的CLR,否则您无法访问比特级别的级别。 – itowlson

1

Int32是一个编译器的内在类型,这意味着编译器有特殊的逻辑来处理它。框架中Int32的实际实现毫无意义。

值得注意的是,Int16,Int32,UInt16,UInt32,Single,Double等大致对应于x86指令集(及其他)本机的类型。创建一个Int36类型同样需要使用本地类型作为纯汇编代码的基础。

+0

谢谢。是的,我猜我会遇到各种各样的性能问题(对齐/填充,需要在ia32等上进行2次读取/写入...)。 –