这与"Watson等人:开始VisualC#第10章:练习4“有关:在People类上实现ICloneable接口,以提供深度复制功能
class People : DictionaryBase: ICloneable
public void DictAdd(Person newPerson)
{
Dictionary.Add(newPerson.Name, newPerson);
public object Clone()
{
People newPeople = new People();
foreach (Person myPerson in Dictionary.Values)
{
Person ClonePerson = (Person)myPerson.Clone();
newPeople.DictAdd(ClonePerson);
}
return newPeople;
}在Person课程中:
public object Clone()
{
Person newPerson = new Person();
newPerson = (Person)newPerson.MemberwiseClone();
newPerson.Age = age;
newPerson.Name = name;
return newPerson;
}要在Program.cs中测试它:
People clonedPeople = (People)PeopleCollection.Clone();
PeopleCollection.Remove("Mick");
myPerson1.Name = "Jock";
myPerson1.Age = 13;
PeopleCollection.DictAdd(myPerson1);
Console.WriteLine("In the current collection \"Mick\" is now: \"{0}\" and his age is: {1}", myPerson1.Name, myPerson1.Age);
Console.WriteLine("But \"Mick\" should remain in the original collection, now cloned.");
foreach (DictionaryEntry p in clonedPeople)
{
Console.WriteLine();
Console.WriteLine("myPerson Name: {0} myPerson.Age: {1}", ((Person)p.Value).Name, ((Person)p.Value).Age);
}这个作品,以及“米克”的原始价值被保留下来。但问题是,首先要在人员和人员类上实现":ICloneable“。不管有没有代码,代码的工作原理都是一样的。
一个相关的问题是他们所称的运行ICloneable的“递归”实现在其示例中的有效性。
public class Content
{
public int Val;
}
public class Cloner: ICloneable
{
public Content MyContent = new Content();
public Cloner(int newVal)
{
MyContent.Val = newVal;
}
public object Clone()
{
Cloner clonedCloner = new Cloner(MyContent.Val);
return clonedCloner;
}
} 已经很不幸地试图让这个递归工作,但是我们最终得到的只是一个StackOverflow。除了使用全局/静态变量退出循环之外,是否有一种优雅的方法可以“递归地”实现这一功能?
发布于 2014-04-06 07:17:19
clonedCloner.MyContent = MyContent.Clone();内容类不实现ICloneable,因此此语句无法编译。你有点迷茫了,我看不出你实际使用的克隆实现是什么,以及这个类与Person有什么关系。
请注意,您并没有实际测试是否有深度克隆。您只通过检查集合没有被修改来测试浅层克隆情况。比如说,深入的克隆测试会改变Mick的一个属性,并检查原始集合是否仍然有一个未经修改的Mick。这才是“深”的真正含义。这在您的代码中是可以的,但是使用MemberwiseClone()会失去优雅点,它不会做任何有用的事情,而且与深度克隆相反。
坦白地说,这本书并没有教你很好的实践。ICloneable接口差一点就被废弃了,应该避免。它是一个中断的接口,它不允许调用方指定需要一个深拷贝还是浅拷贝。通常情况下,它是作为一个浅拷贝实现的,因为它既便宜又简单,而调用方确实想要一个深拷贝。产生一个很难诊断的讨厌的错误。
如果您想支持深度克隆,那么只需向类中添加一个Person DeepClone()方法即可。现在它是显式的和类型安全的。
不要纠缠于此,在书中继续前进。一定要考虑找一个更好的。
发布于 2017-11-11 20:28:56
/* Here is a simple program of Deep copy. This will help you to fully understand ICloneable Interface.
using System;
namespace ICloneableDemo
{
class Program
{
class Demo : ICloneable
{
public int a, b;
public Demo(int x, int y)
{
a = x;
b = y;
}
public override string ToString()
{
return string.Format(" a : " + a + " b: " + b);
}
public object Clone()
{
Demo d = new Demo(a, b);
return d;
}
}
static void Main(string[] args)
{
Demo d1 = new Demo(10, 20);
Console.WriteLine(" d1 : "+d1);
Demo d2 = (Demo)d1.Clone();
Console.WriteLine(" d2 : " + d2);
Demo d3 = (Demo)d2.Clone();
Console.WriteLine(" d3 : " + d3);
Console.WriteLine("Changing the value of d1");
d1.a = 44;
d1.b = 33;
Console.WriteLine(" d1 : " + d1);
Console.WriteLine(" d2 : " + d2);
Console.WriteLine(" d3 : " + d3);
Console.WriteLine("Changing the value of d3");
d3.a = 50;
d3.b = 60;
Console.WriteLine(" d1 : " + d1);
Console.WriteLine(" d2 : " + d2);
Console.WriteLine(" d3 : " + d3);
Console.ReadKey();
}
}
}
/*Output:
d1 : a : 10 b: 20
d2 : a : 10 b: 20
d3 : a : 10 b: 20
Changing the value of d1
d1 : a : 44 b: 33
d2 : a : 10 b: 20
d3 : a : 10 b: 20
Changing the value of d3
d1 : a : 44 b: 33
d2 : a : 10 b: 20
d3 : a : 50 b: 60
*//*注意到输出,当一个对象的值被更改时,它不会影响其他对象。因此,当一个对象被克隆时,它的行为就像一个单独的对象*/
https://stackoverflow.com/questions/22890245
复制相似问题