{
private readonly ArrayList words;
public ClassPrint(ArrayList _words)
{
words = _words;
}
public void printTheWords()
{
foreach(object _word in words)
{
Console.WriteLine(_word.ToString());
Console.WriteLine();
}
Console.ReadLine();
}
static void Main(string[] args)
{
ClassWords testWords = new ClassWords();
ClassPrint testPrint = new ClassPrint(testWords._pWords);
//The First Example
testWords._pWords.Add("The First Example:\n");
testWords._pWords.Add("I become a uncle today!");
testPrint.printTheWords();
//The Second Example
testWords._pWords = new ArrayList();
testWords._pWords.Add("The Second Example:\n");
testWords._pWords.Add("I am very happy now!");
testPrint.printTheWords();
}
}
class ClassWords
{
private ArrayList words = new ArrayList();
public ArrayList _pWords
{
get
{
return words;
}
set
{
words = value;
}
}
}
代码很简单,随便看看就懂了.
Bill Wanger的意思是如果不通过编译器仅仅通过大脑去思考的话,很多程序员会以为是如下输出:
The First Example:
I become a uncle today!
The Second Example:
I am very happy now!
实际的输出应该为
The First Example:
I become a uncle today!
The First Example:
I become a uncle today!
这个其实很好理解,负责输出的classPrint的words是readonly的只能在声明或者构造函数中为其赋值,这个字段在构造函数中被指定为一块内存区域,就不会再做更改.当然这个地方的words字段即使不是readonly的输出结果还是一样的,因为它指向的内存区域跟_pWords已经不一样的,_pWords已经指向了另一段内存区域,它的更改并不会影响到words.
上面扯了半天好像离Bill Wanger的意思越来越远了,哈哈.还是说一下他的意思吧.
Bill Wanger的意思是,下面的定义
public ArrayList _pWords
{
get
{
return words;
}
}
叫做易变(Mutable)只读属性,可以改变该属性的状态,但不能替换它,比如可以用Add(),Remove(),Clear()方法来改变ArrayList属性的状态,但不能让其指向另一个ArrayList.
但是
public ArrayList _pWords
{
get
{
return words;
}
set
{
words = value;
}
}
却可以让它指向另一个ArrayList,这样如果一个客户端代码已经缓存了这个属性原始数据的引用,如果用set方法让它指向新的ArrayList就会显得很突然和奇怪.
我觉得这其实是很正常和比较好理解的,如果类在设计的时候不允许它再指向新的ArrayList(当然这里的Mutable,可以指任何引用类型的数据,比如DataSet等等),那就把这个字段设计为只读,如果所有的实例只允许一份值拷贝,干脆用Sington Pattern.
Bill Wanger写的<<Effective C#>>和<<The C# Core Language Little Black Book>>据说很经典,等看完Anders就可以看这两本了,爽.