首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boxing与ValueType的引用;有什么不同?

Boxing与ValueType的引用;有什么不同?
EN

Stack Overflow用户
提问于 2011-01-27 01:20:28
回答 3查看 583关注 0票数 4

最近有几个关于将ValueType作为对象装箱的问题,特别是在某些情况下是否会发生这种情况。

我意识到我不知道的是,“装箱”ValueType (将其视为引用对象)和简单地通过引用访问它有什么区别,例如使用ref或out关键字(其中传递的只是一个“指针”)?在这两种情况下,值都是您可以指向它的位置(对于对象,它是堆;对于局部作用域的ValueType,它是...具体在哪里?)。

如果我必须猜测,根据我对C++的了解,我会说它是这样工作的:通过引用(假设通过参数关键字)访问的ValueType保留在它的作用域所在的调用堆栈级别上,但在堆栈中创建了指向该变量存储桶的“快捷”指针,并成为堆栈的下一层的一部分。因为值已经存储在内存中(甚至可能是CPU缓存),所以你不必在堆中实例化一些新的东西;唯一的新东西是指针,它是它自己的ValueType (一个IntPtr),它本身存储在堆栈中,所以AFAIK它将比将一些东西放入堆中更快。

这就是正在发生的事情,还是有其他事情正在进行中?

编辑:更清晰:

代码语言:javascript
复制
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);
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-27 08:33:30

类引用可以自由复制,并且允许无限存在。可以将它们视为对象的标识符,这些对象(始终)作为独立的项存储在堆中。为了避免过度使用术语“引用”,我喜欢将它们看作ObjectID。

当一个例程通过引用接受一个参数时,这个引用是一种特殊类型的东西,它在普通的类系统之外(我称之为ParameterReference)。与可以无限期存在的ObjectID不同,ParameterReference只能在被调用函数的持续时间内存在。此外,与始终保存对独立对象的引用的ObjectID不同,ParameterReference保存对堆栈上的局部变量、类对象中的字段、数组中的项或结构中本身与这些描述之一匹配的字段的引用。如果ParameterReference指向一个局部变量,那么一旦该变量超出作用域,该变量就将不复存在;在此之后尝试使用ParameterReference可能会导致数据损坏。但是,由于该变量的作用域至少会一直扩展到被调用的例程退出,而且ParameterReference在那时将不复存在,因此ParameterReference访问不再存在的变量是没有危险的。

票数 3
EN

Stack Overflow用户

发布于 2011-01-27 01:34:45

TakesAnObject(myInt);必须装箱,因为它是作为对象类型(引用类型)接收的。如果目标是一个值类型,那么它将被复制。

TakesAnIntValueType(ref myInt);是对与myInt相同的内存区域的引用,因此如果更改,“两者都会更改”。如果不是ref,该值将被复制。

票数 1
EN

Stack Overflow用户

发布于 2011-01-27 01:23:07

你已经很接近了。当值类型被装箱时,它被复制到一个驻留在GC堆上的对象结构。对象结构具有对象通常的前导,之后的位是blited值类型结构。当它被拆箱时,这个结构被重新复制到堆栈上。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4807659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档