最近有几个关于将 ValueType 装箱为对象的问题,特别是它是否在某些情况下发生。
我意识到我不知道的是,“装箱”ValueType(将其视为引用的对象)和简单地通过引用访问它之间有什么区别,例如使用 ref 或 out 关键字(您传递的只是“指针”)?在这两种情况下,该值都在您可以指向它的某个位置(对于 Object,它是堆,对于本地范围的 ValueType,它是......在哪里,究竟是什么?)。
如果我不得不猜测,根据我对 C++ 的了解,我会说它是这样工作的:通过引用访问的 ValueType(比如说通过 parameter 关键字)保持在其作用域的调用堆栈级别上,但是 "快捷方式”指向该变量在堆栈中的存储桶的指针被创建并成为堆栈下一层的一部分。因为该值已经存储在内存中(甚至可能是 CPU 缓存),所以您不必在堆上实例化新的东西;唯一的新东西是指针,它是它自己的ValueType(一个IntPtr)并且本身存储在堆栈中,所以AFAIK它会比将东西放入堆中更快。
这是正在发生的事情,还是有其他事情正在发生?
编辑:更清晰:
public void TakesAnObject(Object obj) {...}
public void TakesAnIntValueType(ref int myValue) {...}
public void AnotherIntParameterMethod(out int myValue) {...}
...
//this locally-scoped variable is simply created on the stack.
int myInt = 5;
//Performs boxing; an Object is instantiated in the heap that holds the
//variable value from the stack, and that is passed by ref.
TakesAnObject(myInt);
//Apparently does NOT perform boxing, but we're still dealing with a reference.
//So what's going on?
TakesAnIntValueType(myInt);
//Again created on the stack, with the default 0.
int anotherInt;
//Again, apparently no boxing, but we're dealing with a reference to anotherInt.
AnotherIntParameterMethod(anotherInt);