在.Net中,整数是值类型,这意味着它存储在堆栈中.整数也是类(通常是System.Int32).他们有像CompareTo,Equals,......这样的方法,它们应该在堆栈上占用超过四个字节.下面的例子显示它们只占用4个字节:
unsafe static void Main() { int a = 2, b = 4; Console.WriteLine("Adress of a : {0}", (int)&a); Console.WriteLine("Adress of b : {0}", (int)&b); Console.WriteLine("Size of integer: {0}", (int)(&a) - (int)(&b)); }
输出:
Adress of a : 1372876 Adress of b : 1372872 Size of integer: 4
CLR是否对整数和其他值类型(float,long,double,...)进行特殊处理?
不,它们是值类型的事实并不意味着它们存储在堆栈中.这意味着它们存储在变量所在的任何地方.
但是,嘿,让我们与本地变量业务滚动,此时(没有捕获等)他们确实存在于堆栈中.它们需要4个字节.为什么他们需要更多?堆栈上不需要vtable,因为元数据已经指定了类型:没有关于将调用哪些虚拟方法的歧义等.
编辑:正如Shawn的评论中指出的那样(但我想让它更明显),System.Int32是一个结构,而不是一个类.(实际上CLR会创建一个阴影引用类型来覆盖整数的盒装值,但这是另一回事.)
因此,它们应该在堆栈上占用超过四个字节.
这不遵循.编译器和运行时知道确切的类型.值类型不能进一步子类型化,因此不需要"vtable"或其他特定于对象的动态调度机制.
当值类型被装箱以将它们放在堆上时,需要正常的.NET Object头.