值类型在.net中实际如何工作?

值类型在.net中实际如何工作?,.net,.net,有些学术问题,但:像Int这样的值类型实际上是如何工作的 我在mscorlib上使用了Reflector来了解System.Int32是如何实现的,它只是一个继承自System.ValueType的结构。我在一个包含值的位数组的行中寻找一些东西,但我只找到了一个声明为int的字段——这意味着它是一个循环引用 我的意思是,我可以写“inti=14;”,但数字14需要以某种方式存储在某个地方,但我找不到“32位数组”或指针之类的东西 这是编译器的魔法吗?这些魔法类型是规范的一部分吗?(类似于Syst

有些学术问题,但:像Int这样的值类型实际上是如何工作的

我在mscorlib上使用了Reflector来了解System.Int32是如何实现的,它只是一个继承自System.ValueType的结构。我在一个包含值的位数组的行中寻找一些东西,但我只找到了一个声明为int的字段——这意味着它是一个循环引用

我的意思是,我可以写“inti=14;”,但数字14需要以某种方式存储在某个地方,但我找不到“32位数组”或指针之类的东西

这是编译器的魔法吗?这些魔法类型是规范的一部分吗?(类似于System.Attribute或System.Exception是“特殊”类型)

编辑:如果我声明自己的结构,我会向其中添加字段。这些字段是内置类型的,例如int。所以CLR知道我持有int。但是它怎么知道int是32位的,有符号的?仅仅是规范指定了某些基本类型,从而使它们变得“神奇”,还是存在技术机制?假设示例:如果我想声明一个Int36,即一个36位的整数,我可以通过指定“好的,留出36位”来创建一个与Int32完全相同的类型(除了4个额外的ofc位),还是内置原语是固定的,我必须以某种方式解决这个问题(即,通过使用仅设置最后36位的Int64和代码)


如上所述,所有这些都是非常学术性和假设性的,但我一直对此感到好奇。

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

有关更多信息,请参阅第7.2节的分区IIa,“内置类型”。(很抱歉,找不到特定部分的链接。)内置类型有:bool、char、object、string、float32、float64、int[8 | 16 | 32 | 64]、unsigned int[8 | 1632 | 64]、native int(IntPtr)、native unsigned int和typedref。规范指出它们是“在基类库中定义了相应的值类型”,这让我认为Int32实际上是一种围绕“真实”Int32的元数据包装器,它存在于VES级别


其他值类型,如System.Decimal、System.Drawing.Point或您在自己的代码中定义的任何结构,都是非魔法的。

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


值得注意的是,Int16、Int32、UInt16、UInt32、Single、Double等大致对应于x86指令集(以及其他指令集)的本机类型创建一个iT36类型同样需要在纯汇编代码中使用本地类型作为基础。实际上,我很想知道魔法本身是什么。我也是,我希望这个问题是关于值类型如何工作的,即堆栈和堆分配等,但是我自己对此很好奇。如果你想创建一个Int36,你必须以某种方式在C#或IL中对其进行规范,这将迫使你使用一个Int32+Int8或一个忽略最后28位的Int64或其他任何东西。将Int36添加到原始底层虚拟机并让它理解位级表示的唯一方法是实现你自己的CLR a la Mono或R谢谢。因此,在我假设的Int36示例中,除了使用内置类型(即Int64或bool[36])并手动对其余类型进行编码之外,我没有其他选择?正确。请参阅“重新编辑”“请评论您的问题。除非您实现自己的CLR,否则您无法访问位旋转级别。谢谢。是的,我猜我无论如何都会遇到各种性能问题(对齐/填充,需要在ia32上进行2次读/写等)。