এক্সএমএল-সিরিয়ালাইজেবল শ্রেণীর কেন প্যারামিটারলেস কনস্ট্রাক্টর দরকার


173

আমি এক্সএমএল সিরিয়ালাইজেশন করতে কোড লিখছি। নীচে ফাংশন সহ।

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.XML.Serialization.TypeDesc.CheckSupported () এ System.XML.Serialization.TypeScope.GetTypeDesc (টাইপ টাইপ, মেম্বারইনফোর সোর্স ই, বুলিয়ান ডিরেক্টরেসফারেন্স, বুলিয়ান থ্রোঅনআরআর) System.GML.Sialization.ModelCope, মডেল টাইপ, System.XML.Serialization.XMLReflectionImporter.ImportTypeMapping (টাইপ টাইপ, XMLRootAttribute রুট, স্ট্রিং ডিফল্টনামস্পেস) এ System.XML.Serialization.XMLSerializer..ctor (টাইপ টাইপ, স্ট্রিং ডিফল্টনেম নাম স্পেস) এ বুলিয়ান সরাসরি রেফারেন্স)। এক্সএমএলসিরাইজার..ক্টর (প্রকারের ধরণ)

এক্সএমএল সিরিয়ালাইজেশন সফল হতে দেওয়ার জন্য কেন প্যারামিটারলেস কনস্ট্রাক্টর থাকতে হবে?

সম্পাদনা: সিএফডুকের উত্তরের জন্য ধন্যবাদ প্যারামিটারলেস কনস্ট্রাক্টর ব্যক্তিগত বা অভ্যন্তরীণ হতে পারে।


1
আপনি যদি আগ্রহী হন তবে আমি নির্ধারকের প্রয়োজন ছাড়াই কীভাবে অবজেক্ট তৈরি করতে পেলাম (আপডেট দেখুন) - তবে এটি এক্সএমএলসিরাইজারকে মোটেই সহায়তা করবে না - এটি এখনও এটির দাবি করে। কাস্টম কোড জন্য দরকারী, হতে পারে।
মার্ক গ্র্যাভেল

1
XmlSerializerdeserialization জন্য একটি ডিফল্ট প্যারামিটারলেস কনস্ট্রাক্টর প্রয়োজন।
অমিত কুমার ঘোষ

উত্তর:


243

কোনও অবজেক্টের ডি-সিরিয়ালাইজেশন চলাকালীন, কোনও বিষয়টিকে ডি-সিরিয়ালাইজ করার জন্য দায়বদ্ধ বর্গটি ক্রমিক শ্রেণীর একটি উদাহরণ তৈরি করে এবং তারপরে ক্রমবর্ধমান একটি উদাহরণ অর্জন করার পরে ক্রমিক ক্ষেত্র এবং বৈশিষ্ট্যগুলি পপুলেটে যায়।

আপনি আপনার নির্মাতা তৈরি করতে পারেন privateবা internalআপনি যদি চান তবে যতক্ষণ না এটি প্যারামিটারলেস।


1
ওহ, সুতরাং, আমি প্যারামিটারলেস কর্টিকে ব্যক্তিগত বা অভ্যন্তরীণ করতে পারি এবং সিরিয়ালাইজেশন এখনও কাজ করে। আপনার উত্তরের জন্য ধন্যবাদ.
মরগান চেং

2
হ্যাঁ আমি এটি প্রায়শই করি, যদিও আমি এটি গ্রহণ করতে এসেছি যে সর্বজনীন পরামিতিবিহীন নির্মাতারা দুর্দান্ত কারণ তারা আপনাকে জেনারিক এবং নতুন আরম্ভের বাক্য গঠন সহ "নতুন ()" ব্যবহার করতে দেয়। প্যারামিটারযুক্ত কনস্ট্রাক্টরগুলির জন্য স্থির কারখানা পদ্ধতি বা বিল্ডার প্যাটার্ন বাস্তবায়ন ব্যবহার করুন।
সিএফডুক

14
অ্যাক্সেসিবিলিটি টিপটি একটি ভাল তবে আপনার ব্যাখ্যাটি সিরিয়ালকরণের জন্য কোনও অর্থ দেয় না। ডি-সিরিয়ালাইজেশনের জন্য কোনও অবজেক্ট তৈরি করা দরকার। আমি একটি অনুমানকে ঝুঁকি দিয়েছি যে টাইপ-চেক কোডটি এক্সএমএসরিশায়াল কনস্ট্রাক্টরের মধ্যে নির্মিত কারণ একক উদাহরণ উভয় উপায়ে ব্যবহার করা যেতে পারে।
টোমর গ্যাবেল

7
@jwg একটি উদাহরণ হ'ল আপনি যখন কোনও এক্সএমএল কোনও প্রকারের ওয়েব পরিষেবাতে প্রেরণ করছেন এবং সেই উপাদানগুলি আপনার নিজস্ব উপাদানগুলিতে গ্রহণ করতে আগ্রহী নন।
টমর গ্যাবেল

5
মনে রাখবেন যে আপনি নিজের প্যারামিটারলেস কনস্ট্রাক্টর তৈরি করে নিলেও privateবা আপনার যে internalসমস্ত বৈশিষ্ট্যের মানগুলি সিরিয়ালযুক্ত হয়েছিল সেগুলির অবশ্যই publicসেটার থাকতে হবে ।
chrnola

75

এটি একটি সীমাবদ্ধতা XmlSerializer। লক্ষ্য করুন BinaryFormatterএবং DataContractSerializer না এই প্রয়োজন - তারা থার বাইরে একটি uninitialized বস্তুর তৈরি এবং deserialization সময় তা আরম্ভ করতে পারেন।

যেহেতু আপনি এক্সএমএল ব্যবহার করছেন, আপনি DataContractSerializerনিজের শ্রেণিটি [DataContract]/ [DataMember] এর সাথে ব্যবহার এবং চিহ্নিত করার কথা বিবেচনা করতে পারেন তবে নোট করুন যে এটি স্কিমা পরিবর্তন করে (উদাহরণস্বরূপ, এর সমতুল্য নেই [XmlAttribute]- সবকিছু উপাদান হয়ে যায়)।

আপডেট: আপনি যদি সত্যিই জানতে চান তবে কনট্রাক্টরকে ডাকে না করে অবজেক্টটি তৈরি করতে BinaryFormatterব্যবহার করুন FormatterServices.GetUninitializedObject()। সম্ভবত বিপজ্জনক; আমি এটি প্রায়শই ব্যবহার করার পরামর্শ দিচ্ছি না ;- এমএসডিএন-তে মন্তব্যগুলিও দেখুন:

যেহেতু অবজেক্টের নতুন উদাহরণটি শূন্যে আরম্ভ করা হয়েছে এবং কোনও নির্মাণকারী চালিত নয়, বস্তুটি এমন কোনও রাষ্ট্রের প্রতিনিধিত্ব করতে পারে না যা সেই বস্তুর দ্বারা বৈধ হিসাবে বিবেচিত হবে। বর্তমান পদ্ধতিটি কেবল তখনই ডিসিরিয়ালাইজেশনের জন্য ব্যবহার করা উচিত যখন ব্যবহারকারী তাত্ক্ষণিকভাবে সমস্ত ক্ষেত্র পপুলেশন করতে চান। এটি একটি অনিবার্য স্ট্রিং তৈরি করে না, যেহেতু অপরিবর্তনীয় ধরণের খালি উদাহরণ তৈরি করা কোনও উদ্দেশ্য করে না।

আমার নিজস্ব সিরিয়ালাইজেশন ইঞ্জিন রয়েছে, তবে আমি এটিকে ব্যবহার করার ইচ্ছা করি না FormatterServices; আমি জানি যে কনস্ট্রাক্টর (যে কোনও কন্সট্রাক্টর) আসলে কার্যকর হয়েছে uted


ফর্ম্যাটর সার্ভিস.গেটউইনিটিটাইজডঅবজেক্ট (প্রকার) সম্পর্কে পরামর্শের জন্য ধন্যবাদ। :)
ওমর ভ্যান ক্লাইটেন

6
হেহ; দেখা যাচ্ছে যে আমি আমার নিজের পরামর্শ অনুসরণ করি না; প্রোটোবুফ-নেট (বিকল্পভাবে) বয়সেরFormatterServices জন্য ব্যবহারের অনুমতি দিয়েছে
মার্ক গ্র্যাভেল

1
তবে আমি যা বুঝতে পারি না তা হল কোনও ক্ষেত্রে কনস্ট্রাক্টর নির্দিষ্ট না করা হয়েছে, সংকলক একটি পাবলিক প্যারামিটারলেস কনস্ট্রাক্টর তৈরি করে। তাহলে এক্সএমএল ডেসারিয়ালাইজেশন ইঞ্জিনের জন্য কেন এটি যথেষ্ট ভাল নয়?
টুডমো

যদি আমি এক্সএমএলকে ডিসরিয়ালাইজ করতে এবং তাদের নির্মাণকারীর ব্যবহার করে নির্দিষ্ট কিছু বস্তুর সূচনা করতে চাই (যাতে উপাদান / বৈশিষ্ট্যগুলি কনস্ট্রাক্টরের মাধ্যমে সরবরাহ করা হয়) তবে এটি অর্জনের কোনও উপায় আছে কি? সিরিয়ালাইজেশন প্রক্রিয়াটি কাস্টমাইজ করার কোনও উপায় নেই যাতে এটি তাদের নির্মাণকারী ব্যবহার করে বস্তুগুলি তৈরি করে?
শিমি ওয়েইটস্যান্ডলার

1
@ শিমি নোপ; এটি সমর্থিত নয় সেখানে হয় IXmlSerializable , কিন্তু একটি: এটি ঘটে পর কন্সট্রাকটর, এবং খ: এটা খুব কুৎসিত এবং ডান (বিশেষ করে deserialization) পেতে কঠিন - আমি দৃঢ়ভাবে যে বাস্তবায়ন করার চেষ্টা বিরোধীতা করছি, কিন্তু: এটা আপনার কনস্ট্রাকটর ব্যবহার করার অনুমতি দেয় না
মার্ক গ্র্যাভেল

4

উত্তরটি হ'ল: কোনও ভাল কারণেই নয়।

এর নামের বিপরীতে, XmlSerializer ক্লাসটি কেবল সিরিয়ালাইজেশনের জন্যই নয়, ডেসারিয়ালাইজেশনের জন্যও ব্যবহৃত হয়। এটি কাজ করবে কিনা তা নিশ্চিত করার জন্য এটি আপনার ক্লাসে কিছু নির্দিষ্ট পরীক্ষা করে এবং সেগুলির মধ্যে কিছু চেক কেবলমাত্র ডিসিরিয়ালাইজেশনের ক্ষেত্রে প্রাসঙ্গিক, তবে এটি যে কোনও উপায়েই সম্পাদন করে, কারণ আপনি জানেন না যে পরে আপনি কী করতে চান।

আপনার ক্লাসটি যে পরীক্ষায় পাস করতে ব্যর্থ হয়েছে তা হ'ল চেকগুলির মধ্যে একটি যা কেবলমাত্র ডিসিরিয়ালাইজেশনের ক্ষেত্রে প্রাসঙ্গিক। যা ঘটে তা এখানে:

  • Deserialization সময়, XmlSerializerশ্রেণীর আপনার ধরণের দৃষ্টান্ত তৈরি করতে হবে।

  • কোনও প্রকারের উদাহরণ তৈরি করার জন্য, সেই ধরণের কোনও কনস্ট্রাক্টরকে ডাকতে হবে।

  • আপনি যদি কোনও কনস্ট্রাক্টর ঘোষণা করেন না, সংকলক ইতিমধ্যে একটি ডিফল্ট প্যারামিটারলেস কনস্ট্রাক্টর সরবরাহ করেছে তবে আপনি যদি কোনও কনস্ট্রাক্টর ঘোষণা করেন তবে কেবলমাত্র এটিই নির্মাণকারীর জন্য উপলব্ধ।

  • সুতরাং, আপনি যে কনস্ট্রাক্টরটি ঘোষনা করেছেন তা যদি প্যারামিটারগুলি গ্রহণ করে, তবে আপনার ক্লাসটি ইনস্ট্যান্ট করার একমাত্র উপায় হল সেই কনস্ট্রাক্টরকে অনুরোধ করা যা পরামিতিগুলি গ্রহণ করে।

  • তবে XmlSerializerপ্যারামিটারলেস কনস্ট্রাক্টর ব্যতীত অন্য কোন কনস্ট্রাক্টরকে ডাকতে সক্ষম নয়, কারণ প্যারামিটারগুলি গ্রহণকারী কনস্ট্রাক্টরের কাছে কোন প্যারামিটারগুলি পাস করতে হবে তা জানেনা। সুতরাং, এটি আপনার ক্লাসে প্যারামিটারলেস কনস্ট্রাক্টর রয়েছে কিনা তা পরীক্ষা করে দেখা যায় এবং যেহেতু এটি না হয়, এটি ব্যর্থ হয়।

সুতরাং, XmlSerializerক্লাসটি যদি কেবল সিরিয়ালের জন্য প্রযোজ্য চেকগুলি সম্পাদন করে এমনভাবে লেখা থাকে তবে আপনার ক্লাসটি পাস হবে, কারণ সিরিয়ালাইজেশন সম্পর্কে একেবারে কিছুই নেই যা প্যারামিটারলেস কনস্ট্রাক্টর থাকা আবশ্যক করে।

যেমন অন্যরা ইতিমধ্যে চিহ্নিত করেছে, আপনার সমস্যার দ্রুত সমাধান হ'ল প্যারামিটারলেস কনস্ট্রাক্টর যুক্ত করা। দুর্ভাগ্যক্রমে, এটিও একটি নোংরা সমাধান, কারণ এর অর্থ হ'ল আপনার কোনও readonlyসদস্য নির্মাণকারীর পরামিতি থেকে আরম্ভ করতে পারবেন না ।

এই সমস্ত কিছুর পাশাপাশি, XmlSerializerক্লাসটি এমনভাবে লেখা যেতে পারে যাতে প্যারামিটারলেস কনস্ট্রাক্টর ছাড়াই ক্লাসগুলির deserialization করতে দেওয়া যায়। "ফ্যাক্টরি মেথড ডিজাইন ডিজাইনের প্যাটার্ন" (উইকিপিডিয়া) ব্যবহারের জন্য যা যা লাগবে তা হ'ল । এর চেহারা থেকে, মাইক্রোসফ্ট সিদ্ধান্ত নিয়েছে যে এই নকশার প্যাটার্নটি ডটনেট প্রোগ্রামারদের জন্য অনেক বেশি উন্নত, যাদের স্পষ্টতই এই জাতীয় জিনিসগুলির সাথে অযৌক্তিকভাবে বিভ্রান্ত হওয়া উচিত নয়। মাইক্রোসফ্ট অনুসারে, ডটনেট প্রোগ্রামারদের পরামিতিহীন নির্মাতাদের আরও ভালভাবে আঁকতে হবে।


হ্যাঁ আপনি বলছেন, For no good reason whatsoever,তাহলে আরও বলতে হবে, XmlSerializer is not capable of invoking any constructor except a parameterless constructor, because it does not know what parameters to pass to constructors that accept parameters.যদি কোনও কনস্ট্রাক্টরের কাছে কোন প্যারামিটারগুলি পাস করতে হয় তা যদি এটি না জানে, তবে কারখানায় কী কী প্যারামিটারগুলি পাস করতে হবে তা কীভাবে জানবে? বা কোন কারখানা ব্যবহার করতে হবে? আমি এই সরঞ্জামটি আরও সহজবোধ্যভাবে ব্যবহার করার জন্য কল্পনা করতে পারি না - আপনি একটি শ্রেণিকৃতকে ডিসরিয়ালাইজড করতে চান, তারপরে ডিসরিয়ালাইজারকে একটি ডিফল্ট উদাহরণ তৈরি করতে দিন এবং তারপরে আপনার ট্যাগ করা প্রতিটি ক্ষেত্রকে পপুলেট করুন। সহজ।
ছক

0

প্রথমত, এটি ডকুমেন্টেশনে যা লেখা আছে । আমি মনে করি এটি আপনার শ্রেণীর ক্ষেত্রগুলির মধ্যে একটি, প্রধান নয় - এবং আপনি কীভাবে ডেসরিয়ালাইজারটিকে এটি ডাব্লু / ও প্যারামিটারলেস নির্মাণ করতে চান?

আমি মনে করি কনস্ট্রাক্টরকে বেসরকারী করে তোলার মতো কাজ রয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.