2011-11-11 146 views
4

我有一個MyItems列表。 MyItem可能會或可能不會引用其同伴。c#克隆交叉引用列表

List<MyItem> myList = new List<MyItem>(); 
myList.add(...) //add all 8 items 
myList[1].RefTo = myList[3]; 
myList[5].RefTo = myList[2]; 
myList[7].RefTo = myList[5]; 

     Item 0 
     Item 1 ----+ 
    +---> Item 2  | 
    |  Item 3 <---+ 
    |  Item 4 
    +--- Item 5 <---+ 
     Item 6  | 
     Item 7 ----+ 

我需要做一個整個列表的克隆。新列表中的每個MyItem都是舊列表中的MyItems的新副本(不是引用),並且新列表中的所有引用都應該指向新列表中的項目。在那時,即使舊列表和舊MyItems被完全刪除,新列表也可以工作。

我已經在MyItem中實現了ICloneable接口,因此可以通過調用MyItem.Clone()來克隆該項目。但是,克隆副本仍然引用舊列表中的MyItems。

如何使用新列表中的對象更新MyItems的引用? 示例代碼將不勝感激。

+0

我幾乎想知道如果你將需要克隆的名單被保留,而不是列表中的項目...... – Daryl

回答

7

您只需將您的列表序列化爲內存流並將其反序列化並創建一個克隆。由於每個對象只序列化,一旦你RefTo場將在克隆副本,如你所願,包括循環引用

namespace ConsoleApplication1 
{ 
    [Serializable] 
    class MyItem 
    { 
     public int MyProperty { get; set; } 
     public MyItem RefTo { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<MyItem> list1 = new List<MyItem>(); 
      list1.Add(new MyItem() { MyProperty = 1 }); 
      list1.Add(new MyItem() { MyProperty = 2 }); 
      list1.Add(new MyItem() { MyProperty = 3 }); 

      list1[1].RefTo = list1[0]; 
      list1[2].RefTo = list1[1]; 

      using (MemoryStream stream = new MemoryStream()) 
      { 
       var bformatter = new BinaryFormatter(); 
       bformatter.Serialize(stream, list1); 
       stream.Seek(0, SeekOrigin.Begin); 
       List<MyItem> clonedCopyList = (List<MyItem>)bformatter.Deserialize(stream); 
      } 
     } 
    } 
} 
+0

+1,可能是最簡單的方法,而不是寫一個DeepCopy方法(它可能更快?但絕對非常困難,特別是對於枚舉類等) – Rob

+0

10循環引用是什麼? –

+0

它也將被處理 –