2012-10-11 74 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"));