理解C#的string类型

有关C# String类型究竟是值类型还是引用类型,在很多C#学习者中都或多或少造成过困惑,多数是因为这个情况:

string a = "aaa";

string b = a;

b = "bbb";

或者是这么几行代码:

 public void Swap(string s1, string s2)

{

     string temp=s1;

     s1=s2;

     s2=temp;

}

这时候结果一打印,结果发现a的值还没有变,Swap也没有成功,这时候就会有幻觉:是不是没有传引用啊? 呵呵,C#的String声明的是class String,当然是传引用,不会这么粗暴的打乱“声明为class就是传引用”这种规则的。

 分析一下:

string a = "aaa"; //==> a----->new String("aaa")

string b = a;        //==> b----->a, 传引用

b = "bbb";          //==> b----->new String("bbb"), 传引用,b指向了一个新的字符串,a并没有变。 

Swap函数也是这样,比如说传了a, b进去(a="aaa", b="bbb"),     //s1----->a, s2----->b    

string temp=s1;//temp----->s1----->a    

s1=s2;               //s1----->s2----->b;    

s2=temp;          //s2----->temp----->a 结果是,s1和s2确实是Swap了,但是这种结果并不会影响到a和b

 

又好比下面这个例子:

  1. class Class1
  2. {
  3. static void StrChange(string str)
  4. {
  5. str = "hellow";
  6. }
  7. static void Main()
  8. {
  9. string str = "123";//申明一个字符串
  10. StrChange(str);//调用方法
  11. Console.WriteLine(str);//输出字符串
  12. }
  13. }

    输出的结果是 "123" 。

    那么,string 到底是值类型还是引用类型?有人会说,如果是值类型,结果倒还说的过去.但是string 的定义不是应该是引用类型么?如果是引用类型的话.输出的结果难度不应该是: "hellow"么?

    解答这个问题的关键在于,C# string类型是特殊的引用类型,它的实例是只读的。这个地方要搞清楚语法和实现的区别 。在C#的语法中,

    ◆static void StrChange(string str) 是值传递

    ◆static void StrChange(ref string str) 是引用传递

    但在实现上,static void StrChange(string str) 这种值传递,在函数体内对str进行修改之前,与函数外部的变量指向同一块内存,是“引用”传递,但在函数体内对str修改后,就会触发对该str重新分配一块内存。

    所以说,String 是引用类型,不过是不可变的。对字符串做一些操作(比如大小写的转换、+=), 实际上是重新创建了一个字符串。这也是为什么在做大量字符串拼接的时候要使用StringBuilder 而不用+=。

posted @ 2012-10-10 20:44  顿金  阅读(194)  评论(0编辑  收藏  举报