2012-10-11 77 views
0

我有一个类表示一些数据和一个集合类(从CollectionBase派生)。当我将集合类的一个实例分配给另一个实例时,它通过引用进行分配,所以我实现了ICloneable接口。实现克隆方法

public void Add(object item) 
    { 
     InnerList.Add(item); 
    } 

    public object Clone() 
    { 
     MyCollection clone = new MyCollection(); 

     foreach (MyClass item in this) 
     { 
      clone.Add(item); 
     } 

     return clone; 
    } 

现在一切工作正常。但是,当我浏览元素并将它们逐个添加到克隆实例时,为什么不通过引用添加呢? Add方法如何将它添加到InnerList中?为什么不通过参考添加?如果我添加一个这个集合的实例,让我们说一个List并更改列表中的元素?原始实例是否会更改?

编辑:这是MyClass

public class MyClass 
{ 
    public bool IsEnabled { get; set; } 

    public string Parent { get; set; } 

    public string Child { get; set; } 

    public MyClass() 
    { 
     IsEnabled = false; 
     Parent = string.Empty; 
     Child = string.Empty; 
    } 

    public MyClass(bool isEnabled, string parent, string child) 
    { 
     IsEnabled = isEnabled; 
     Parent = parent; 
     Child = child; 
    } 

    public bool IsValid() 
    { 
     return (!Parent.Equals(string.Empty) && 
       !Child.Equals(string.Empty)); 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
     { 
      return false; 
     } 

     if (!obj.GetType().IsAssignableFrom(this.GetType())) 
     { 
      return false; 
     } 

     return ((MyClass)obj).Parent.Equals(Parent) || 
       ((MyClass)obj).Child.Equals(Child); 
    } 

    public bool Equals(MyClass myClass) 
    { 
     if (myClass == null) 
     { 
      return false; 
     } 

     return myClass.Parent.Equals(Parent) || 
       myClass.Child.Equals(Child); 
    } 

    public override int GetHashCode() 
    { 
     return Parent.GetHashCode(); 
    } 
} 

编辑2:我所做的是

MyClass item = new MyClass(true, "test", "test"); 
MyCollection collection = new MyCollection(); 

collection.Add(item); 

MyCollection newCollection = new MyCollection(); 
newCollection = (MyCollection) collection.Clone(); 

newCollection[0].Parent = "changed"; 

现在在这之后我预计该集合[0] .Parent将改为“改变”也,但它仍然保持不变。不是通过参考克隆实例添加的吗?

回答

1

如果集合中的项目是引用类型,则它们通过引用添加。如果您添加了克隆的集合,它将不会修改原始集合。

+0

但是为什么集合的引用类型和我创建了自定义类是不? – hattenn

+0

@hattenn - 应该是。你能分享“MyClass”的代码吗? –

+0

我已添加到问题中。 – hattenn

1

这取决于你想如何实现克隆方法。如果你想返回对象的浅拷贝,那么你可以使用Object.MemberwiseClone方法。如果你想返回深度复制,那么你可以使用BinaryFormatter来序列化和反序列化对象/集合。这将返回一个新的对象/集合。

0
[Serializable] 
    class CustomClass 
    { 
     int _id; 
     string _value; 

     public CustomClass(int id, string value) 
     { 
      _id = id; 
      _value = value; 
     } 
    } 

    [Serializable] 
    class CustomClassCollection 
    { 
     private IList<CustomClass> _list = null; 

     public CustomClassCollection() 
     { 
      _list = new List<CustomClass>(); 
     } 

     public void Add(CustomClass a) 
     { 
      _list.Add(a); 
     } 
    } 



    public static class ObjectCopier 
    { 
     public static T Clone<T>(this T source) 
     { 
      if (!typeof(T).IsSerializable) 
      { 
       throw new ArgumentException("The type must be serializable.", "source"); 
      } 

      if (Object.ReferenceEquals(source, null)) 
      { 
       return default(T); 
      } 

      IFormatter formatter = new BinaryFormatter(); 
      Stream stream = new MemoryStream(); 
      using (stream) 
      { 
       formatter.Serialize(stream, source); 
       stream.Seek(0, SeekOrigin.Begin); 
       return (T)formatter.Deserialize(stream); 
      } 
     } 
    } 

这样使用它:

 CustomClassCollection a = new CustomClassCollection(); 
     CustomClassCollection b = ObjectCopier.Clone<CustomClassCollection>(a); 

     a.Add(new CustomClass(1, "A")); 
     a.Add(new CustomClass(2, "B")); 
     a.Add(new CustomClass(3, "C")); 

     b.Add(new CustomClass(1, "A")); 
     b.Add(new CustomClass(2, "B"));