2009-08-16 59 views
5

我有這個類:DataContractSerializer的序列化不是類的成員,它繼承了ISerializable

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

namespace Grouping 
{ 
    [Serializable] 
    public class Group<T> : HashSet<T> 
    { 
     public Group(string name) 
     { 
      this.name = name; 
     } 

     protected Group(){} 

     protected Group(SerializationInfo info, StreamingContext context):base(info,context) 
     { 
      name = info.GetString("koosnaampje"); 
     } 

     public override void GetObjectData(SerializationInfo info,StreamingContext context) 
     { 
      base.GetObjectData(info,context); 
      info.AddValue("koosnaampje", Name); 
     } 

     private string name; 
     public string Name 
     { 
      get { return name; } 
      private set { name = value; } 
     } 
    } 
} 

當它從HashSet的它必須實現ISerializable的,因此受保護的構造和GetObjectData方法繼承。 以前我用BinaryFormatter成功地序列化和反序列化了這個類。

因爲我希望能夠檢查序列化器生成的輸出,我想切換到DataContractSerializer。

我寫這個測試:

[TestMethod] 
public void SerializeTest() 
{ 
    var group = new Group<int>("ints"){1,2,3}; 
    var serializer = new DataContractSerializer(typeof (Group<int>)); 
    using (var stream=File.OpenWrite("group1.xml")) 
    { 
     serializer.WriteObject(stream,group); 
    } 
    using (var stream=File.OpenRead("group1.xml")) 
    { 
     group = serializer.ReadObject(stream) as Group<int>; 
    } 
    Assert.IsTrue(group.Contains(1)); 
    Assert.AreEqual("ints",group.Name); 
} 

測試失敗,因爲Name屬性爲空! (雖然整數正確(但)序列化) 發生了什麼?

編輯:它與名稱支持字段是私人沒有關係。公開的結果是一樣的。

+0

爲什麼數據協定序列化程序會將其序列化?沒有'[DataContract]'或'[DataMember]'屬性。 – 2009-08-16 18:58:39

+0

@John:我當然試過。但我得到一個異常,說明:類型'Grouping.Group'1 [[System.Int32,mscorlib,版本= 2.0.0.0,文化=中立,PublicKeyToken = b77a5c561934e089]]'不能ISerializable並具有DataContractAttribute屬性..我認爲DataContractSerializer對使用SerializableAttribute標記的類非常滿意。 – Dabblernl 2009-08-16 19:27:58

+0

@John - DCS現在可以做到這一點......它曾經是純粹的「我要求合同」,但現在如果錯過了,它也會推斷出一個。腐敗,海事組織。它像BinaryFormatter一樣工作 - 即它查看**字段**;這很容易成爲它可能完成的最糟糕的方式。但我並不苦。 – 2009-08-16 19:38:44

回答

5

這與ISerializable無關; DataContractSerializer根本就不使用ISerializable(它將使用IXmlSerializable,但你不想這樣做...)

大多數串行,包括XmlSerializerDataContractSerializer(和數據綁定,對於這個問題),將收藏視爲與實體不同。它可以是一個另一個,但不是兩個。因爲它檢測到它是一個「集合」,所以它將序列化內容(即集合中的任何內容),而不是屬性(Name等)。

你應該封裝一個集合,而不是繼承它。

另外;要正確使用DataContractSerializer,最好添加/[DataContract]屬性。例如:

[Serializable, DataContract] // probably don't need [Serializable] 
public class Group<T> 
{ 
    [DataMember] 
    public HashSet<T> Items { get; private set; } 

    protected Group() 
    { 
     Items = new HashSet<T>(); 
    } 
    public Group(string name) : this() 
    { 
     Name = name; 
    } 
    [DataMember] 
    public string Name {get ;private set;} 
} 
+0

+1很好的解釋 – 2009-08-16 19:45:38

+0

謝謝,繼承的內容集合確實是正確的序列化,但不是繼承類的成員。我將調整代碼以表明這一點。 – Dabblernl 2009-08-16 19:53:46

相關問題