2015-07-21 91 views
1

所以我有多個引用其實例中的其他類的自定義類。我知道序列化如何工作,但我該如何處理對象引用?目標是將對象保存爲xml或二進制文件,以便以後可以恢復狀態。在維護對象引用的同時序列化C#對象

在這個簡化的例子中,人員是通過id來標識的,並且有一個被稱爲朋友的其他Person對象的列表。

public class Person{ 
     public int id; 
     public List<Person> friends; 

} 

如何序列化和反序列化這個例子中,並保持對象引用是否完整?另外我認爲反序列化可能會很棘手,如果它試圖還原引用尚未反序列化的人員。

+0

您究竟如何發送和接收這些對象? – Adam

+0

只是保存/本地加載它們(到文件)XML或二進制 – Sunspear

回答

4
[XmlRootAttribute("Person")] 
public class Person{ 
    [XmlAttribute("_id")] 
    public int id; 
    [XmlElement("friends")] 
    public List<Person> friends; 
} 

然後使用XmlSerializer類來創建一個XML文件和/或你的對象 https://msdn.microsoft.com/en-us/library/58a18dwa.aspx

+0

非常酷,我不知道了'_id'屬性。我用我的答案中的代碼對它進行了測試,「Bob's Firend,斯科特的朋友」返回true。 (然而,我不得不讓對象序列化一個'Person'而不是'List '而我通過'bob'而不是'people')。 –

1

如果您搭載在WCF您可以跟蹤引用和使用DataContract屬性和設置IsReference = true,你則需要使用DataContractSerializer序列化您的數據。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Runtime.Serialization; 

namespace SandboxConsole 
{ 
    internal class Program 
    { 
     public static void Main() 
     { 
      var bob = new Person {Id = 0}; 
      var scott = new Person {Id = 1}; 
      var dave = new Person {Id = 2}; 

      bob.Friends.Add(scott); 
      bob.Friends.Add(dave); 
      scott.Friends.Add(dave); 

      var people = new List<Person>(); 
      people.Add(bob); 
      people.Add(scott); 
      people.Add(dave); 

      using (var fs = File.Create("Test.xml")) 
      { 
       var ser = new DataContractSerializer(typeof(List<Person>)); 
       ser.WriteObject(fs, people); 
      } 

      List<Person> people2; 
      using (var fs = File.OpenRead("Test.xml")) 
      { 
       var ser = new DataContractSerializer(typeof(List<Person>)); 
       people2 = (List<Person>)ser.ReadObject(fs); 
      } 

      Console.WriteLine("Are these daves the same dave?"); 
      Console.WriteLine("List dave, bob's friend - {0}", ReferenceEquals(people2[2], people2[0].Friends[1])); 
      Console.WriteLine("Bob's firend, scott's friend - {0}", ReferenceEquals(people2[0].Friends[1], people2[1].Friends[0])); 
      Console.ReadLine(); 
     } 
    } 

    [DataContract(IsReference = true)] 
    public class Person 
    { 
     public Person() 
     { 
      Friends = new List<Person>(); 
     } 

     [DataMember] 
     public int Id { get; set; } 

     [DataMember] 
     public List<Person> Friends { get; private set; } 
    } 
} 

嘗試使用IsRefrence = false或不包含該參數(其默認爲false)運行上述試驗程序,它會爲的是相同的對象測試輸出false。但是,如果將其設置爲IsRefrence = false,它將輸出true作爲相同對象的測試。

編輯:一個重要的提示,也沒有辦法,我知道的,使RefrenceEquals(people[0], people2[0])輸出true