【.net 深呼吸】序列化中的「引用保留」

假設 K 類中有兩個屬性/字段的類型相同,而且它們引用的是同一個對象實例,在序列化的默認處理中,會爲每一個引用單獨生成數據。spa

看看下面兩個類。code

    [DataContract]
    public class 帥哥
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
        [DataMember]
        public float Height { get; set; }
        [DataMember]
        public ContactInfo ContactData1 { get; set; }
        [DataMember]
        public ContactInfo ContactData2 { get; set; }
    }

    [DataContract]
    public class ContactInfo
    {
        [DataMember]
        public string Phone { get; set; }
        [DataMember]
        public string Email { get; set; }
    }

假設 ContactInfo 表示聯繫方式,帥哥有兩個聯繫方式。xml

 

-------------------------------------------------------------對象

            ContactInfo cinfo = new ContactInfo
            {
                Email = "big_pig@珊瑚蟲.com",
                Phone = "118116"
            };

            帥哥 wg = new 帥哥
            {
                Name = "王小八",
                Age = 99,
                Height = 1.414f,
                ContactData1 = cinfo,
                ContactData2 = cinfo
            };

在上面代碼中,帥哥實例的兩種聯繫方式都引用了同一個 ContactInfo 對象。若是把該帥哥實例序列化。blog

            DataContractSerializer szr = new DataContractSerializer(wg.GetType());
            MemoryStream mstream = new MemoryStream();
            szr.WriteObject(mstream, wg);

就會獲得如下XML文檔:ci

<帥哥 xmlns="http://schemas.datacontract.org/2004/07/SampleApp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Age>99</Age>
  <ContactData1>
    <Email>big_pig@珊瑚蟲.com</Email>
    <Phone>118116</Phone>
  </ContactData1>
  <ContactData2>
    <Email>big_pig@珊瑚蟲.com</Email>
    <Phone>118116</Phone>
  </ContactData2>
  <Height>1.414</Height>
  <Name>王小八</Name>
</帥哥>

 

從上面生成的XML文檔可知,引用的儘管是同一個實例,但很顯然,ContactInfo 的數據被寫入了兩次。文檔

----------------------------------------------------------get

那麼,若是改成保留引用呢,看string

            DataContractSerializerSettings settings = new DataContractSerializerSettings();
            settings.PreserveObjectReferences = true;             DataContractSerializer szr = new DataContractSerializer(wg.GetType(), settings);
            MemoryStream mstream = new MemoryStream();
            szr.WriteObject(mstream, wg);

將 PreserveObjectReferences 屬性設置爲 true,表示同一實例引用只寫入一次。it

 

修改後生成的XML文檔以下:

<帥哥 z:Id="1" xmlns="http://schemas.datacontract.org/2004/07/SampleApp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <Age>99</Age>
  <ContactData1 z:Id="2">
    <Email z:Id="3">big_pig@珊瑚蟲.com</Email>
    <Phone z:Id="4">118116</Phone>
  </ContactData1>
  <ContactData2 z:Ref="2" i:nil="true" />
  <Height>1.414</Height>
  <Name z:Id="5">王小八</Name>
</帥哥>

 

你看,這一回的 XML 是否是比剛纔的要簡短了?由於同一個 ContactInfo 實例只寫入了一次,而且給其中一個引用分配一個 id,後面若是還用到,就直接使用對象的 id 就好了,這樣避免了重複寫入內容。

 

好了,今天分享的內容不能稱得上是高大上,但老周以爲,是有價值的,但願對各位有用。

相關文章
相關標籤/搜索