2011-11-11 2 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 (참조하지 않음)의 새 사본이며 새 목록의 모든 참조는 새 목록의 항목을 가리켜 야합니다. 그러면 새 목록은 이전 목록에서도 작동하고 이전 MyItem은 완전히 삭제됩니다.

MyItem.Clone()을 호출하여 항목을 복제 할 수 있도록 MyItem에서 ICloneable 인터페이스를 구현했습니다. 그러나 복제 된 복사본은 여전히 ​​이전 목록의 MyItems를 참조합니다.

MyItems의 참조를 새 목록의 개체로 업데이트하려면 어떻게해야합니까? 샘플 코드는 대단히 감사하겠습니다.

+0

나는 거의 당신이 목록을 복제해야하는 거라면 궁금하네요 포함 원하는대로 RefTo 필드가 복제 된 복사본에 보존됩니다 일단 각 객체는 직렬화이기 때문에, 목록의 항목이 아닙니다 ... – Daryl

답변

7

간단히 말해서 목록을 메모리 스트림으로 serialize하고 역 직렬화하여 복제본을 만드는 것입니다. 당신이 순환 참조

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 메서드를 작성하는 것입니다 (더 빠를 수는 있겠지만, 특히 Enumerables 등에서는 특히 어렵습니다) – Rob

+0

순환 참조는 어떻게됩니까? –

+0

그것도 처리됩니다 –