2009-08-16 5 views
5

विरासत वर्ग के सदस्य Serializing नहीं मैं इस वर्ग है: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 विधि कार्यान्वित करना होगा विरासत के रूप में। पूर्व में मैंने इस वर्ग को बाइनरीफॉर्मेटर के साथ सफलतापूर्वक क्रमबद्ध और deserialized किया।

क्योंकि मैं धारावाहिक द्वारा उत्पन्न आउटपुट का निरीक्षण करने में सक्षम होना चाहता हूं, मैं 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); 
} 

परीक्षण कारण विफल रहता है नाम संपत्ति शून्य है:

मैं इस परीक्षण लिखा है! (पूर्णांक (डी) सही ढंग से क्रमबद्ध हैं) क्या हो रहा है?

संपादित करें: इसका नाम बैकिंग फ़ील्ड निजी होने के साथ कुछ लेना देना नहीं है। इसे सार्वजनिक बनाना एक ही परिणाम है।

+0

डेटा अनुबंध serializer क्यों क्रमबद्ध करता है? कोई '[DataContract]' या '[DataMember]' विशेषता नहीं है। –

+0

@ जॉन: मैंने निश्चित रूप से कोशिश की। लेकिन मुझे एक अपवाद मिला कि: 'ग्रुपिंग। ग्रुप'1 टाइप करें [[System.Int32, mscorlib, संस्करण = 2.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = b77a5c561934e089]]' ISerializable नहीं हो सकता है और DataContractAttribute विशेषता है .. मैंने सोचा कि DataContractSerializer SerializableAttribute के साथ चिह्नित कक्षाओं के साथ पूरी तरह से खुश होगा। – Dabblernl

+0

@ जॉन - डीसीएस अब ऐसा करता है ... यह शुद्ध होता था "मैं एक अनुबंध की मांग करता हूं", लेकिन अब यह गायब होने पर भी इसका अनुमान लगाएगा। एक भ्रष्टाचार, आईएमओ। यह बाइनरीफॉर्मेटर की तरह काम करता है - यानी यह ** फ़ील्ड ** देखता है; जो आसानी से किया जा सकता है सबसे खराब संभव तरीका है। लेकिन मैं कड़वा नहीं हूँ। –

उत्तर

5

ISerializable के साथ ऐसा करने के लिए कुछ भी नहीं है; DataContractSerializer बस नहीं उपयोगISerializable (यह IXmlSerializable उपयोग करेगा, लेकिन आपको लगता है कि ऐसा करने के लिए ... नहीं करना चाहती) XmlSerializer और DataContractSerializer सहित

अधिकांश serializers, (और डेटा-बाइंडिंग, उस बात के लिए), इकाइयों के लिए अलग संग्रह संग्रह। यह एक या अन्य हो सकता है, लेकिन दोनों नहीं। क्योंकि यह पता लगाता है कि यह एक "संग्रह" है, यह सामग्री (यानी सेट में जो कुछ भी है) को क्रमबद्ध करता है, गुण नहीं (Name आदि)।

आप एक संग्रह है, बजाय इनहेरिट यह संपुटित चाहिए।

इसके अलावा; DataContractSerializer का सही उपयोग करने के लिए, [DataMember]/[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 अच्छा स्पष्टीकरण –

+0

धन्यवाद, विरासत की सामग्री संग्रह वास्तव में सही ढंग से serialized थे, लेकिन विरासत वर्ग के सदस्यों नहीं। मैं इसे दिखाने के लिए कोड समायोजित करूंगा। – Dabblernl

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^