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


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

看看下面兩個類。

    [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 表示聯系方式,帥哥有兩個聯系方式。

 

-------------------------------------------------------------

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

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

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

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

就會得到以下XML文檔:

<帥哥 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 的數據被寫入了兩次。

----------------------------------------------------------

那么,如果改為保留引用呢,看

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

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

 

修改后生成的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 就行了,這樣避免了重復寫入內容。

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM