C#值类型装箱后能改变其值吗

当把一个值类型赋值给引用类型,这个过程可以看作是"装箱"。

object a = 10;

以上,堆栈上的过程大致是:
1、在栈上开辟空间给变量a
2、在堆上开辟空间,习惯上把该空间看作是"箱子"
3、把10"装箱"

 

1
变量a指向堆上值为10的对象,换句话说,变量a的值是堆上对象的地址。

 

现在,如果我们想让a=11,可能首先想到的是:让"箱子"内的10自增1,变成11。

 

尝试这样做:


oject a = 10;
a++;


结果报错:++无法运用于object类型。也就是说,++无法应用于引用类型。

 

那好办,先拆箱变成值类型,然后自增1呢?


object a = 10;
((int)a)++;
 

结果还是报错:增量或减量运算符的操作数必须为变量、属性或索引器。
((int)a)++,相当于10++,相当于10=10+1,相当于10=11,难怪会报错!

 

好吧,++帮不了我们,但我们可以把拆箱后的值赋值给另外一个变量:


object a = 10;
int temp = (int)a;
a = temp + 1;
 

这样,a的值就是11了。

 

这次,堆栈上大致是这样:
1、在栈上开辟空间给变量a
2、在堆上开辟空间,习惯上把该空间看作是"箱子"
3、把10"装箱"
4、在栈上开闭空间给变量temp
5、把a的值拆箱后,赋值给变量temp,此时temp的值为10
6、在堆上又开辟另外的空间
7、把temp + 1,即11装箱

 

2
变量指向堆上值为11的对象。堆上值为10的对象则等待GC的回收。

 

当然,以上的做法是"曲线救国",完全可以这样:


object a = 10;
a = 11;
 

之所以这样绕,是因为想在原先值的基础上得到新的值。

 

最后,回到本篇的主题:值类型装箱后能改变其值吗?答案是不能。装箱后的值具有"恒定性(Immutable)"的特点。就像本篇中的object a = 10,如果想给引用类型变量a赋上新的值,就直接a=11,就可以了。10一旦装箱,就无法改变其值了。

posted @ 2014-09-15 15:49  Darren Ji  阅读(945)  评论(0编辑  收藏  举报

我的公众号:新语新世界,欢迎关注。