String到底是值类型还是引用类型(C#)

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

  1. //值类型
  2.  
    int a = 1;
  3.  
    int b = a;
  4.  
    a = 2;
  5.  
    Console.WriteLine("a is {0},b is {1}", a, b);
  6.  
     
  7.  
    //引用类型
  8.  
    string str1 = "ab";
  9.  
    string str2 = str1;
  10.  
    str1 = "abc";
  11.  
    Console.WriteLine("str1 is {0},str2 is {1}", str1, str2);
  12.  
    Console.Read();

 

输出结果:

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

从运行结果可以看出: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是引用类型,只是编译器对其做了特殊处理。

String到底是值类型还是引用类型(C#)

上一篇:confd+consul配置prometheus


下一篇:【转】Alertmanager高可用