2011-04-07 11 views
29

सी # में, मेरे पास एक कक्षा है जिसमें व्युत्पन्न संपत्ति है जिसे एक्सएमएल के माध्यम से क्रमबद्ध किया जाना चाहिए। हालांकि, एक्सएमएल क्रमिकरण (डिफ़ॉल्ट रूप से) पढ़ने = केवल गुणों को क्रमबद्ध नहीं करता है। मैं इस के आसपास इतनी तरह एक खाली सेटर को परिभाषित करते हुए काम कर सकते हैं:रीडोनली प्रॉपर्टी को क्रमबद्ध करने के लिए फोर्स एक्सएमएल सीरियलाइजेशन

public virtual string IdString 
{ 
    get { return Id.ToString("000000"); } 
    set { /* required for xml serialization */ } 
} 

लेकिन वहाँ मेरे अपने ISerializable कार्यान्वयन लेखन से कम एक क्लीनर और अधिक शब्दार्थ सही तरीका क्या है?

+0

यदि मैं इसे सही ढंग से समझता हूं, तो आपके पास एक आईडीस्ट्रिंग है जिसे एक्सएमएल फ़ाइल में क्रमबद्ध किया जा रहा है, लेकिन वर्ग को deserialized जब अनदेखा किया गया है? –

+0

आईडीस्ट्रिंग हमेशा आईडी संपत्ति से ली जाएगी, जो धारावाहिक और deserialized मिलता है। – Chris

+10

इस मामले में आप IdString क्यों serialise करते हैं? – Justin

उत्तर

13

संक्षेप में, नहीं। XmlSerializer के साथ आप या तो IXmlSerializable (जो गैर-तुच्छ है) लागू कर सकते हैं, या एक मूल डीटीओ (जो पूरी तरह से पढ़ा जाता है) लिखें और फिर डीटीओ मॉडल से अपने मुख्य मॉडल में अनुवाद करें।

नोट करें कि कुछ मामलों मेंDataContractSerializer एक व्यवहार्य विकल्प है, लेकिन यह एक्सएमएल पर समान नियंत्रण प्रदान नहीं करता है। हालांकि, डीसीएस के साथ आप कर सकते हैं:

[DataMember] 
public int Id { get; private set; } 
+3

'IXmlSerializable' वास्तव में इस समस्या के लिए वास्तव में अच्छी तरह से काम करता है, खासकर अगर आप केवल serializing और deserializing नहीं हैं, और यह करना मुश्किल नहीं है। इस पर एक नज़र डालें: http://www.codeproject.com/Articles/43237/How-to-Iplement-IXmlSerializable- सही – cjbarth

18

ईमानदारी से इस रूप में लंबे समय के रूप में यह

प्रलेखित है मेरे लिए बहुत बुरा नहीं लगता है आप शायद एक अपवाद फेंक चाहिए अगर सेटर वास्तव में कहा जाता है:

/// <summary> 
/// Blah blah blah. 
/// </summary> 
/// <exception cref="NotSupportedException">Any use of the setter for this property.</exception> 
/// <remarks> 
/// This property is read only and should not be set. 
/// The setter is provided for XML serialisation. 
/// </remarks> 
public virtual string IdString 
{ 
    get 
    { 
     return Id.ToString("000000"); 
    } 
    set 
    { 
     throw new NotSupportedException("Setting the IdString property is not supported"); 
    } 
} 
+8

क्या इस अपवाद के कारण निराशाजनक विफल होने का कारण नहीं होगा? – primfaktor

+2

@primfaktor हां, लेकिन जैसा कि मैंने सवाल को समझ लिया है कि यह बिंदु है (यह कभी भी निराशाजनक नहीं होगा)। यदि वह वांछित व्यवहार नहीं था तो आप बसटर में कुछ भी नहीं कर सकते थे, या स्ट्रिंग को पार्स भी कर सकते थे और 'आईडी' प्रॉपर्टी सेट कर सकते थे (संभवतः केवल तभी अगर इसे पहले से सेट नहीं किया गया हो)। – Justin

+1

ओह, यकीन है। यह लिखते समय मैं कैफीन पर काफी कम था। – primfaktor

1

समाधान थोड़ा आगे अक्रमांकन के रूप में अच्छी तरह से काम करने के लिए अनुमति देने के लिए लेने के लिए ...

public class A 
{ 
    private int _id = -1; 

    public int Id 
    { 
     get { return _id; } 
     set 
     { 
      if (_id < 0) 
       throw new InvalidOperationException("..."); 

      if (value < 0) 
       throw new ArgumentException("..."); 

      _id = value; 
     } 
    } 
} 

यह Id को 0 से अधिक या उसके बराबर मान के लिए बिल्कुल एक बार सेट करने की अनुमति देगा। इसके बाद इसे सेट करने के किसी भी प्रयास के परिणामस्वरूप InvalidOperationException होगा। इसका मतलब है कि XmlSerializer deserialization के दौरान Id सेट करने में सक्षम हो जाएगा, लेकिन यह कभी भी बाद में बदला नहीं जा सकता है। ध्यान दें कि यदि संपत्ति एक संदर्भ प्रकार है तो आप केवल शून्य की जांच कर सकते हैं।

यदि आपके पास serialize/deserialize के लिए बहुत से पढ़ने-योग्य गुण हैं तो यह सबसे अच्छा समाधान नहीं हो सकता है क्योंकि इसे बहुत सारे बॉयलरप्लेट कोड की आवश्यकता होगी। हालांकि, मुझे यह 1-2 रीड-ओनली गुणों वाले वर्गों के लिए स्वीकार्य माना गया है।

अभी भी एक हैक है, लेकिन यह कम से कम छोटा अधिक मजबूत है।

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