【C#】String是值类型还是引用类型

MSDN中明确指出String 是引用类型而不是值类型,但String表面上用起来却像是值类型,这又是什么原因呢?
首先从下面这个例子入手:

//值类型
int a = 1;
int b = a;
a = 2;
Console.WriteLine("a is {0},b is {1}", a, b);

//引用类型
string str1 = "ab";
string str2 = str1;
str1 = "abc";
Console.WriteLine("str1 is {0},str2 is {1}", str1, str2);
Console.Read();

输出结果:

//结果:
//a is 2,b is 1
//str1 is abc,str2 is ab

从运行结果可以看出:str2的值还是ab,并没有随着 str1 值的改变而改变。如果string是引用类型,按理Str1和Str指针都指向同一内存地址,如果Str的内容发生改变,Str1应该也会相应变化。此例子,看着string更像是值类型。 但是MSDN却说String是引用类型。究其原因,是因为string对象是不可变的,包括长度和其中任何字符都是不可以改变的。

String的不变性

原理
string 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。有的时候看来似乎修改了,实际是string经过了特殊处理,每次改变值时都会建立一个新的string对象,变量会指向这个新的对象,而原来的还是指向原来的对象,所以不会改变。这也是string效率低下的原因。如果经常改变string的值则应该使用StringBuilder而不使用string。
分析
在例子中str1=”ab”,这时在内存中就将“ab”存下来,如果再创建字符串对象,其值也等于“ab”,str2=”ab”,则并非再重新分配内存空间,而是将之前保存的“ab”的地址赋给str2的引用,这就能印证例子2中的结果。而当str1=”abc”其值发生改变时,这时检查内存,发现不存在此字符串,则重新分配内存空间,存储“abc”,并将其地址赋给str1,而str2依然指向“ab”的地址。可以印证例子中的结果。

结论

String是引用类型,只是编译器对其做了特殊处理

参考资料

原博客地址http://www.cnblogs.com/yank/archive/2011/10/24/2204145.html
MSDN上的相关讨论https://social.msdn.microsoft.com/Forums/zh-CN/ce580186-86d9-45f7-b5ff-20302caf1324/c?forum=visualcshartzhchs

猜你喜欢

转载自blog.csdn.net/It_sharp/article/details/81288353