2014-04-06 18 views
1

这涉及到“沃森等人:开始的Visual C#第10章:练习4”: 落实人民类ICloneable接口,提供深度复制能力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); 
     } 

这是有效的,并且“Mick”的原始值被保留。 但是问题在于首先在Person和People类上实现“: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; 
    } 
}   

曾试图悲惨得到这个递归工作他们所说的在他们投放了“递归”实施ICloneable的疗效,但所有我们最终是一个StackOverflow。在使用全局/静态变量退出循环之后,是否存在一个优雅的方式来实现这个“递归?”

+0

“代码在使用或不使用它时都是相同的。”你是什​​么意思,更具体一点。代码“没有它”是什么样的?同样在你的第二个例子中,你有两个克隆类,是一个错误? – Euphoric

+0

对不起,我的意思是:类人:DictionaryBase而不是类人:DictionaryBase:ICloneable其他代码编辑,对不起。 –

回答

4
clonedCloner.MyContent = MyContent.Clone(); 

Content类未实现ICloneable,因此该语句无法编译。你有点失落,我看不到你实际使用的Cloner的实现方式,以及这个类如何用来处理Person。

请注意,您并未真正测试您是否获得了深度克隆。您只通过检查集合没有被修改来测试浅层克隆情况。例如,深度克隆测试会改变Mick的一个属性,并检查原始集合是否还有未修改的Mick。这真的是“深”的意思。在你的代码中没关系,但是你失去了使用MemberwiseClone()的优雅点,它没有做任何有用的事情,并且与深层克隆相反。

坦率地说,这本书没有教你很好的做法。 ICloneable接口已被弃用,应该避免使用。它是一个破损的界面,它不允许调用者指定是否需要深层或浅层副本。通常,它是以浅拷贝的形式实现的,因为它既便宜又容易,而调用者真的需要深度拷贝。产生一个很难诊断的令人讨厌的错误。

如果你想支持深度克隆,那么只需在你的课堂上添加一个Person DeepClone()方法即可。现在它是明确的类型安全。

不要纠缠于此,在书中继续前进。考虑找一个更好的。

+0

〜汉斯:感谢您的洞察力,“MyContent.Clone()”令人沮丧:装箱。 –

+0

首选的方法是从VS10“升级”以利用内置的“DeepClone?”。 另外,考虑到“新”操作符在内存中创建对象的深层副本,缺少D/Ling C#语言规范,是否有比MSDN更好的描述“新”操作符? viz-(愚蠢的问题?)“新”的代码是否包含memberwiseclone,反之亦然? –

+0

该死的,没有。继续前进,这将在几个月内有意义。 –

1
/* 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 
*/ 

/*注意输出,当一个对象的值发生变化,也不会影响别人 。因此,当一个对象被克隆时,它的行为就像一个单独的对象*/