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

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

object a = 10;

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


变量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装箱


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

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

object a = 10;
a = 11;
 

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

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

时间: 2024-11-09 05:58:14

C#值类型装箱后能改变其值吗的相关文章

6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱 引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并说明一些有关它们的重要原理. 最后通过一个简单的示例代码说明装箱拆箱带来的性能损耗. 声明变量的内部机制 在.NET程序中,当你声明一个变量,将在内存中分配一块内存.这块内存分为三部分:1,变量名:2,变量类型:3,变量值. 下图揭示了声

.NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱

一.“堆”,“栈”专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道...“堆”,“栈”是什么?哦,这个知道... 之前我也写过一篇堆栈的文章,不过写的不深刻,剖析的也不全面,所以今天也参考了一些大牛的资料. 一.预备知识—程序的内存分配    一个由C/C++编译的程序占用的内存分为以下几个部分    1.栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等.其    操作方式类似于数据结构中的栈.栈是一个内存数组,是一个LIFO(last-in  f

使用接口更改已装箱的值类型中的字段

先看下面一段代码 namespace 使用接口更改已装箱值类型的字段 { //point是一个值类型 internal struct Point { private Int32 m_x, m_y; public Point(Int32 x, Int32 y) { m_x = x; m_y = y; } public void Change(int x, int y) { m_x = x; m_y = y; } public override string ToString() { return

值类型,引用类型,装箱,拆箱

值类型包括原类型(Sbyte.Byte.Short.Ushort.Int.Uint.Long.Ulong.Char.Float.Double.Bool.Decimal).枚举(enum).结构(struct),引用类型包括:类.数组.接口.委托.字符串等. 值型就是在栈中分配内存,在申明的同时就初始化,以确保数据不为NULL: 引用型是在堆中分配内存,初始化为null,引用型是需要GARBAGE COLLECTION来回收内存的,值型不用,超出了作用范围,系统就会自动释放! 值类型的变量包含自身

C# 类型基础 值类型和引用类型

引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复制(Shallow Copy)和深度复制(Deep Copy),浅度复制和深度复制又是以如何复制引用类型成员来划分的.由此又引出了引用类型和值类型,以及相关的对象判等.装箱.拆箱等基础知识.索性从最基础的类型开始自底向上写起. 值类型和引用类型 先简单回顾一下C#中的类型系统.C# 中的类型一共分为

C#值类型和引用类型用C语言理解

我刚用C#一个来月,可能理解得不对,还请大家指教. 读懂文章你需要对C语言的指针有所理解. 需要注意区别:对C\C++来说,任何类型都可以当成C#的"引用类型",因为有指针. [在内存上] void foo() { int aaa = 0; //值类型,aaa在Stack上分配(SUB ESP,XX) int* paaa = new int[123]; //引用类型,paaa在Heap上分配,HeapAlloc(GetProcessHeap()...) foo2(&aaa);

[转] 值类型与引用类型(中)

本文将介绍以下内容: 类型的基本概念 值类型深入 引用类型深入 值类型与引用类型的比较及应用 1. 引言 上回[第八回:品味类型---值类型与引用类型(上)-内存有理]的发布,受到大家的不少关注,我们从内存的角度了解了值类型和引用类型的所以然,留下的任务当然是如何应用类型的不同特点在系统设计.性能优化等方面发挥其作用.因此,本回是对上回有力的补充,同时应朋友的希望,我们尽力从内存调试的角度来着眼一些设计的分析,这样就有助于对这一主题进行透彻和全面的理解,当然这也是下一回的重点. 从内存角度来讨论

漫谈值类型和引用类型

一.前言 从这个简单程序的输出结果,你想到了什么?是不是与你心中想的结果不一致?是不是觉得输出的结果应该为:i is 1,o is 8,o2 is 8 二.程序执行前                              图 2 我们都知道,每一个方法在执行前,操作系统会给方法内每个变量分配内存空间.从图2中就可以看出,在执行前各变量(i,o,o2)已分配了内存,且各自都有初始值. 从图中,可以发现变量i和变量o,o2有些许不同.变量i在内存中存储的值和程序中的值是一样的,都是0:变量o,o

C#中值类型和引用类型

本文将介绍C#类型系统中的值类型和引用类型,以及两者之间的一些区别.同时,还会介绍一下装箱和拆箱操作. 值类型和引用类型 首先,我们看看在C#中哪些类型是值类型,哪些类型是引用类型. 值类型: 基础数据类型(string类型除外):包括整型.浮点型.十进制型.布尔型. 整型(sbyte.byte.char.short.ushort.int.uint.long.ulong ) 浮点型(float 和 double ) 十进制型(decimal ) 布尔型(bool ) 结构类型(struct) 枚