Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot明显Red shoe在Bill的脚上是错误的。为什么会这样呢?看一下图因为 我们使用Shoe作为一个引用类型来取代值类型。当一个引用被拷贝的时候,只拷贝了其指针,所以我们不得不做一些额外的工作来确保我们的引用类型看起来更像是值类型。幸运的是我们拥有一个名为ICloneable接口可以帮助我们。这个接口基于一个契约,所有的Dude对象都将定义一个引用类型如何被复制以确保我们的Shoe不会发生共享错误。我们所有的类都可以使用ICloneable接口的clone方法来复制类对象。
public class Shoe : ICloneable {
public string Color;
#region ICloneable Members
public object Clone () {
Shoe newShoe = new Shoe();
newShoe.Color = Color.Clone() as string;
return newShoe;
}
#endregion
}
在Clone()方法内我们创建了一个Shoe,拷贝所有引用类型并拷贝所有值类型并返回一个新的对象实例。你可能注意到string类已经实现了ICloneable接口,因此我们可以调用Color.Clone()。因为Clone()返回的是一个对象的引用,我们不得不进行类型转换在我们设置Shoe的Color前。接下来,我们用CopyDude()方法去克隆shoe。
public Dude CopyDude () {
Dude newPerson = new Dude();
newPerson.Name = Name;
newPerson.LeftShoe = LeftShoe.Clone() as Shoe;
newPerson.RightShoe = RightShoe.Clone() as Shoe;
return newPerson;
}
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.CopyDude();
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图示如下: 包装实体