参考自:http://www.cnblogs.com/fox23/archive/2008/07/26/understanding-immutable-in-csharp.html
有一种很简单也很受用的编程(不仅仅是C#)宗旨,就是所谓的"Immutability"(不可变性质)。如果一个类的实例是immutable的,那么我们把这个类也称作immutable class。
这样说来,似乎immutable的确是一个相当简单的东西,不过从以下几个问题中你可以找到使用immutable对象的便利之处。我们可以想一下,为什么编写一个多线程的应用程序要相对困难一些?那是因为在访问某些资源(对象或者其他OS掌管的资源)的时候线程间的同步问题总是会令人感到头疼。那为什么会有线程访问同步的问题呢?那是因为在多线程,多个对象之间,要保证他们的的多个读和写的操作不会引起冲突是一件很困难的事。那么这些冲突为什么会造成我们不希望的结果呢,其实关键就在于这里的“写”操作,因为只有它会改变对象的状态,给我们带来非预计的结果。
System.String
还是从这个“知名”的Immutable class开始谈吧,这个经常使用的类型被设计为immutable,当你改变一个String对象的时候,一个新的对象副本将被创建。尽管几乎所有的 C#教科书都会谈及这个问题,但是有时候我们似乎并不在意,于是我们经常会编写类似这样的语句:
这里的str本身并没有改变,只是创建了一个"CNblogs"的副本。
很显然,对string频繁进行这样的操作会在内存中制造N多string对象,多数情况下那并不是我们所希望的。当然,这时候我们知道可以用System.Text.StringBuilder这样一个安全的方式来构造可变的字符串对象。
OK,上述内容几乎所有C#语言相关书籍上的说法都是一致的。但是String真的是完全immutable的么?
我想,这个倒未必哦,至少有这么几个方式是可以使得String不那么immutable的:
1. 直接操作指针
2. 使用反射
m_stringLength:This is the logical length of the string, the one returned by String.Length.
从以上对String的讨论中我们至少可以得到以下几条immutable的优势
不过我还是想提醒一下,immutable还是有副作用的,就比如之前提到的产生很多垃圾对象。
C#中immutable的实现
1. 经典的immutable class
这个例子几乎无须再解释,每次changeNumber的时候就构造一个新的Contact对象。
C# 对immutability的支持离不开这两个关键字: const和readonly。
2. C#3.0中的immutable
C#3的编译器生成的匿名类型是immutable的,所有的字段都是private的,所有的属性都是只能get(使用reflector可以看到)。下面的代码将会在编译时报错:“Error 1 Property or indexer 'AnonymousType#1.A' cannot be assigned to -- it is read only ....”