一般來說,我們總是想克隆一個引用類型和拷貝一個值類型。記住這點將有助於你解決調試時發生的錯誤。讓我們更進一步分析並清理一下Dude類實現,使用ICloneable接口來代替CopyDude()方法。
public class Dude : ICloneable {
public string Name;
public Shoe RightShoe;
public Shoe LeftShoe;
public override string ToString () {
return (Name + " : Dude!, I have a " + RightShoe.Color +
" shoe on my right foot, and a " +
LeftShoe.Color + " on my left foot.");
}
#region ICloneable Members
public object Clone () {
Dude newPerson = new Dude();
newPerson.Name = Name.Clone() as string;
newPerson.LeftShoe = LeftShoe.Clone() as Shoe;
newPerson.RightShoe = RightShoe.Clone() as Shoe;
return newPerson;
}
#endregion
}
我們再來修改Main()中的方法:
public static void Main () {
Class1 pgm = new Class1();
Dude Bill = new Dude();
Bill.Name = "Bill";
Bill.LeftShoe = new Shoe();
Bill.RightShoe = new Shoe();
Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";
Dude Ted = Bill.Clone() as Dude;
Ted.Name = "Ted";
Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";
Console.WriteLine(Bill.ToString());
Console.WriteLine(Ted.ToString());
}
最後,運行我們的程序,會得到如下的輸出:
Bill : Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot.
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot.
還有些比較有意思的東西,比如System.String重載的操作符=號就實現了clones方法,因此你不用過於擔心string類的引用復制問題。但是你要注意內存的消耗問題。如果你仔細查看上圖,由於string是引用類型所以需要一個指針指向堆中的另一個對象,但是看起來它像是一個值類型。