C#中的String是引用类型和值类型的综合体,兼有二者的特点。
1、String 是类,是引用类型,在堆上分配内存。为什么要把String设计为class ,因为String要处理比较多的业务逻辑,比如大小写转换,拆分字符串等。
2、String 是不可变字符串。按理说,string是引用类型,在赋值或者调用方法传递参数的时候,是“复制引用”,对引用的值进行修改,应该产生副作用。但实际情况并非如此。请看下面的代码。
View Code
1 class Program
2 {
3 static void Main()
4 {
5 string s1 = "Andy";
6 string s2 = s1;
7 s2 = "Bill";
8 }
9 }
在上面的代码中,按理说,修改了s2为Bill,s1 也应该为Bill。调试会发现,s1 仍然为Andy。这是因为string 是不可变字符串,每次修改相当于重新创建一个string。这一点其实很类似值类型的“整体拷贝”。
那么进一步思考,为什么要把string 设计为不可变字符串呢?有以下原因:
(1)字符串不可变,解决了多线程同步的问题。展开来讲,可以认为string的设计是为了函数式编程。函数式编程的核心就是,变量不可变,每次修改相当于重新创建新的变量,这就是为了解决多线程同步的问题。多线程同时访问一个变量,如果大家都修改,肯定会导致变量的不一致性。为了解决这个问题,线程在修改的时候,不是修改原来的变量,而是根据原来的变量创建一个新的变量。这样的话,产生的副作用,不会影响到其他的线程。
(2)字符串是计算机处理最多的类型,字符串不可变,就可以让内容相等的string变量,指向同一个string实例,从而可以大大地减少堆上string的实例,节约内存。这也是string 留用的目的。
3、string 被设计为sealed,这一点也很像值类型,所有的值类型都是sealed的。
4、string 的==操作符被重写,变成内容的比较。