2008-11-06 12 views
146

मैं एक्सएमएल क्रमबद्ध करने के लिए कोड लिख रहा हूं। नीचे समारोह के साथ।एक्सएमएल-सीरियलज़ेबल क्लास को पैरामीटर रहित कन्स्ट्रक्टर की आवश्यकता क्यों है

public static string SerializeToXml(object obj) 
{ 
    XmlSerializer serializer = new XmlSerializer(obj.GetType()); 
    using (StringWriter writer = new StringWriter()) 
    { 
     serializer.Serialize(writer, obj); 
     return writer.ToString(); 
    } 
} 

यदि तर्क पैरामीटर रहित कन्स्ट्रक्टर के बिना कक्षा का उदाहरण है, तो यह अपवाद फेंक देगा।

बिना क्रिया के अपवाद: System.InvalidOperationException: CSharpConsole.Foo धारावाहिक नहीं किया जा सकता क्योंकि यह एक parameterless निर्माता नहीं है। System.Xml.Serialization.TypeDesc.CheckSupported() System.Xml.Serialization.TypeScope.GetTypeDesc (प्रकार प्रकार, MemberInfo sourc ई, बूलियन directReference, बूलियन throwOnError) पर System.Xml.Serialization पर पर। ModelScope.GetTypeModel (प्रकार प्रकार, बूलियन प्रत्यक्ष संदर्भ) System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping (प्रकार प्रकार, XmlRootAttribute जड़, स्ट्रिंग defaultNamespace) पर System.Xml.Serialization.XmlSerializer..ctor पर (प्रकार टाइप करें, स्ट्रिंग डिफ़ॉल्ट नाम स्थान) System.Xml.Serialization.XmlSerializer..ctor (टाइप प्रकार)

एक्सएमएल क्रमबद्धता को सफल होने की अनुमति देने के लिए पैरामीटर रहित कन्स्ट्रक्टर क्यों होना चाहिए?

संपादित करें: सीएफड्यूक के उत्तर के लिए धन्यवाद। पैरामीटर रहित कन्स्ट्रक्टर निजी या आंतरिक हो सकता है।

+1

यदि आप रुचि रखते हैं, तो मुझे पता चला कि कन्स्ट्रक्टर की आवश्यकता के बिना ऑब्जेक्ट्स कैसे बनाएं (अपडेट देखें) - लेकिन यह XmlSerializer को बिल्कुल भी मदद नहीं करेगा - यह अभी भी इसकी मांग करता है। कस्टम कोड के लिए उपयोगी, शायद। –

+0

'XmlSerializer' को deserialization के लिए एक डिफ़ॉल्ट पैरामीटर रहित कन्स्ट्रक्टर की आवश्यकता है। –

उत्तर

208

किसी ऑब्जेक्ट के डी-सीरियलाइजेशन के दौरान, ऑब्जेक्ट को डी-सीरियलाइज करने के लिए ज़िम्मेदार वर्ग धारावाहिक वर्ग का एक उदाहरण बनाता है और उसके बाद धारावाहिक फ़ील्ड और गुणों को पॉप्युलेट करने के लिए केवल उदाहरण प्राप्त करने के बाद प्राप्त होता है।

यदि आप चाहें तो अपने कन्स्ट्रक्टर private या internal बना सकते हैं, बस इसके पैरामीटर के रूप में लंबे समय तक।

+0

ओह, इसलिए, मैं पैरामीटर रहित सीटीआर निजी या आंतरिक बना सकता हूं और क्रमबद्धता अभी भी काम करता है। आपके उत्तर के लिए धन्यवाद। –

+1

हां मैं अक्सर ऐसा करता हूं, हालांकि मैं स्वीकार करता हूं कि सार्वजनिक पैरामीटर रहित कन्स्ट्रक्टर बहुत अच्छे हैं क्योंकि वे आपको जेनेरिक और नए प्रारंभिक वाक्यविन्यास के साथ "नया()" उपयोग करने की अनुमति देते हैं। पैरामीटेड कन्स्ट्रक्टर के लिए स्थैतिक फैक्ट्री विधियों या बिल्डर पैटर्न कार्यान्वयन का उपयोग करें। – cfeduke

+11

एक्सेसिबिलिटी टिप एक अच्छा है, लेकिन आपकी स्पष्टीकरण क्रमबद्धता के लिए कोई समझ नहीं लेती है। एक वस्तु को केवल डी-सीरियलाइजेशन के लिए बनाया जाना चाहिए। मुझे लगता है कि टाइप-चेक कोड XmlSerializer कन्स्ट्रक्टर में बनाया गया है क्योंकि एक ही उदाहरण दोनों तरीकों से उपयोग किया जा सकता है। –

0

सबसे पहले, यह documentation में लिखा गया है। मुझे लगता है कि यह आपके वर्ग के खेतों में से एक है, मुख्य नहीं - और आप deserialiser को इसे कैसे बना सकते हैं w/o पैरामीटर रहित निर्माण?

मुझे लगता है कि कन्स्ट्रक्टर निजी बनाने के लिए एक कामकाज है।

65

यह XmlSerializer की एक सीमा है। ध्यान दें कि BinaryFormatter और DataContractSerializer को इसकी आवश्यकता नहीं है - वे ईथर से एक अनियमित वस्तु बना सकते हैं और इसे deserialization के दौरान प्रारंभ कर सकते हैं।

आप एक्सएमएल उपयोग कर रहे हैं के बाद से, आप DataContractSerializer का उपयोग करने और [DataContract]/[DataMember] के साथ अपने वर्ग अंकन पर विचार हो सकता है, लेकिन ध्यान दें कि यह स्कीमा में परिवर्तन (उदाहरण के लिए, वहाँ [XmlAttribute] का कोई बराबर है - सब कुछ तत्वों हो जाता है)।

अपडेट: यदि आप वास्तव में जानना चाहते हैं, BinaryFormatter एट अल FormatterServices.GetUninitializedObject() का उपयोग बिना कन्स्ट्रक्टर का आविष्कार किए ऑब्जेक्ट बनाने के लिए करें।शायद खतरनाक; मैं यह भी अक्सर का उपयोग कर यह भी देखें ;-p MSDN पर टिप्पणी की अनुशंसा नहीं करते:

क्योंकि वस्तु का नया उदाहरण शून्य करने के लिए आरंभ नहीं हो जाता और कोई कंस्ट्रक्टर्स चलाए जा रहे हैं, वस्तु नहीं दर्शा सकते हों एक ऐसी स्थिति जिसे माना जाता है, उस वस्तु द्वारा मान्य है। वर्तमान विधि का उपयोग केवल deserialization के लिए किया जाना चाहिए जब उपयोगकर्ता सभी क्षेत्रों को तुरंत पॉप्युलेट करने के लिए का इरादा रखता है। यह एक अनियमित स्ट्रिंग नहीं बनाता है, क्योंकि एक अपरिवर्तनीय प्रकार एक अपरिवर्तनीय प्रकार का उदाहरण कोई उद्देश्य प्रदान करता है।

मैं अपने own क्रमबद्धता इंजन है, लेकिन मैं इसे FormatterServices का उपयोग कर रही है इरादा नहीं है; मुझे यह जानना बहुत पसंद है कि एक कन्स्ट्रक्टर (कोई कन्स्ट्रक्टर) वास्तव में निष्पादित किया गया है।

+0

FormatterServices.GetUninitializedObject (Type) के बारे में टिप के लिए धन्यवाद। :) –

+4

हे; पता चला है कि मैं अपनी सलाह का पालन नहीं करता; protobuf-net (वैकल्पिक रूप से) * उम्र * –

+1

के लिए 'FormatterServices' उपयोग की अनुमति है, लेकिन जो मुझे समझ में नहीं आता है, अगर कोई कन्स्ट्रक्टर निर्दिष्ट नहीं किया गया है, तो संकलक सार्वजनिक पैरामीटर रहित कन्स्ट्रक्टर बनाता है। तो एक्सएमएल deserialization इंजन के लिए इतना अच्छा क्यों नहीं है? – toddmo

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

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