Lau*_*arn 1 c# recursion icloneable
这涉及到《Watson et al: Beginning Visual C# Chapter 10:exercise 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;
}
Run Code Online (Sandbox Code Playgroud)
在 Person 类中,我们有:
public object Clone()
{
Person newPerson = new Person();
newPerson = (Person)newPerson.MemberwiseClone();
newPerson.Age = age;
newPerson.Name = name;
return newPerson;
}
Run Code Online (Sandbox Code Playgroud)
要在 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);
}
Run Code Online (Sandbox Code Playgroud)
这有效,并且保留了“Mick”的原始值。但问题是首先要在 Person 和 People 类上实现“: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;
}
}
Run Code Online (Sandbox Code Playgroud)
我们曾痛苦地尝试过让这个递归起作用,但最终我们得到的只是一个 StackOverflow。除了使用全局/静态变量来退出循环之外,是否存在一种优雅的方法来“递归”实现此循环?
clonedCloner.MyContent = MyContent.Clone();
Run Code Online (Sandbox Code Playgroud)
Content 类未实现 ICloneable,因此该语句无法编译。你有点迷失了,我看不到你实际使用的 Cloner 的实现以及这个类与 Person有什么关系。
请注意,您实际上并没有测试是否获得了深度克隆。您仅通过检查集合是否未被修改来测试浅克隆情况。例如,深度克隆测试会改变米克的属性,并检查原始集合是否仍然有未修改的米克。这才是真正的“深”的意义。这在您的代码中是可以的,但是您会失去使用 MemberwiseClone() 的优雅点,它不会做任何有用的事情,并且与深度克隆相反。
坦率地说,这本书并没有教给你很好的实践。ICloneable 接口险些被弃用,应该避免。这是一个损坏的接口,它不允许调用者指定是否需要深拷贝或浅拷贝。很多时候,它被实现为浅拷贝,因为它便宜且简单,而调用者确实想要一个深拷贝。产生一个很难诊断的令人讨厌的错误。
如果您想支持深度克隆,只需Person DeepClone()向您的类添加一个方法即可。现在它是显式的且类型安全的。
别再纠结这个了,继续看书吧。请考虑寻找一个更好的。
| 归档时间: |
|
| 查看次数: |
3653 次 |
| 最近记录: |