সমস্যা সমাধান!
ঠিক আছে, তাই অবশেষে আমি সেখানে পৌঁছেছি (স্বীকারোক্তি দিয়ে এখান থেকে প্রচুর সহায়তায় !)।
সুতরাং সংক্ষেপে:
লক্ষ্যসমূহ:
- আমি এক্সএমএলকিউন্ডলে যেতে চাইনিমেনটেনেন্সের মাথা ব্যাথার কারণে রুটে চাইনি।
- একবার সমাধান পাওয়া গেলে, আমি চাইছিলাম এটি অন্যান্য অ্যাপ্লিকেশনগুলিতে দ্রুত প্রয়োগ করা হোক।
- বিমূর্ত প্রকারের সংগ্রহগুলি পাশাপাশি পৃথক বিমূর্ত বৈশিষ্ট্যগুলি ব্যবহার করা যেতে পারে।
- আমি কংক্রিটের ক্লাসে "বিশেষ" জিনিসগুলি নিয়ে আসলেই বিরক্ত করতে চাইনি।
চিহ্নিত করা বিষয়গুলি / পয়েন্টগুলি দ্রষ্টব্য:
- এক্সএমএসআরশায়ালার কিছু দুর্দান্ত শীতল প্রতিবিম্ব সম্পাদন করে তবে এটি বিমূর্ত প্রকারের ক্ষেত্রে খুব সীমাবদ্ধ থাকে (যেমন এটি কেবল বিমূর্তের ধরণের উদাহরণ দিয়ে কাজ করবে, সাবক্লাস নয়)।
- এক্সএমএল অ্যাট্রিবিউট সাজসজ্জারগুলি নির্ধারণ করে যে কীভাবে এক্সএমএলসিরালাইজার তার বৈশিষ্ট্যগুলির সাথে আচরণ করে। শারীরিক প্রকারটিও নির্দিষ্ট করা যেতে পারে তবে এটি একটি সংকীর্ণ সংযোগ তৈরি করে এটি ক্লাস এবং সিরিয়ালাইজারের মধ্যে তৈরি করে (ভাল নয়)।
- IXMLSerializable প্রয়োগ করে এমন একটি ক্লাস তৈরি করে আমরা আমাদের নিজস্ব এক্সএমএলসিরাইজার প্রয়োগ করতে পারি ।
সমাধান
আমি একটি জেনেরিক ক্লাস তৈরি করেছি, যাতে আপনি জেনেরিক প্রকারটিকে বিমূর্ত প্রকার হিসাবে নির্দিষ্ট করেন যা আপনি কাজ করবেন। এটি ক্লাসটিকে অ্যাবস্ট্রাক্ট টাইপ এবং কংক্রিট টাইপের মধ্যে "অনুবাদ" করার ক্ষমতা দেয় যেহেতু আমরা কাস্টিংকে হার্ড-কোড করতে পারি (যেমন আমরা এক্সএমএলসিরাইজারের ক্যান এর চেয়ে আরও তথ্য পেতে পারি)।
আমি তখন আইএক্সএমএলসিরাইজেবল ইন্টারফেস বাস্তবায়িত করেছি , এটি বেশ সোজা এগিয়ে রয়েছে, তবে সিরিয়ালিংয়ের সময় আমাদের এটি নিশ্চিত করা দরকার যে আমরা এক্সএমএলে কংক্রিট শ্রেণীর প্রকারটি লিখি, তাই ডি-সিরিয়ালিং করার সময় আমরা এটি আবার ফেলে দিতে পারি। এটি সম্পূর্ণরূপে যোগ্য হতে হবে তা লক্ষ করাও গুরুত্বপূর্ণ is যে এটি দুটি শ্রেণীর মধ্যে যে সম্মেলনগুলি রয়েছে তার মধ্যেএখানে অবশ্যই একটি সামান্য ধরণের চেকিং এবং স্টাফ রয়েছে যা হওয়া দরকার।
যেহেতু এক্সএমএলসিরাইজার কাস্ট করতে পারে না, তাই এটি করার জন্য আমাদের কোড সরবরাহ করতে হবে, সুতরাং অন্তর্নিহিত অপারেটরটি তখন ওভারলোড হয়ে যায় (আপনি এমনকি এটি করতে পারেন তা আমি কখনও জানতাম না!)।
অ্যাবস্ট্রাক্ট এক্সএমএলসায়ারাইজারের কোডটি হ'ল:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace Utility.Xml
{
public class AbstractXmlSerializer<AbstractType> : IXmlSerializable
{
public static implicit operator AbstractType(AbstractXmlSerializer<AbstractType> o)
{
return o.Data;
}
public static implicit operator AbstractXmlSerializer<AbstractType>(AbstractType o)
{
return o == null ? null : new AbstractXmlSerializer<AbstractType>(o);
}
private AbstractType _data;
public AbstractType Data
{
get { return _data; }
set { _data = value; }
}
public AbstractXmlSerializer()
{
}
public AbstractXmlSerializer(AbstractType data)
{
_data = data;
}
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
string typeAttrib = reader.GetAttribute("type");
if (typeAttrib == null)
throw new ArgumentNullException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractType).Name +
"' because no 'type' attribute was specified in the XML.");
Type type = Type.GetType(typeAttrib);
if (type == null)
throw new InvalidCastException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractType).Name +
"' because the type specified in the XML was not found.");
if (!type.IsSubclassOf(typeof(AbstractType)))
throw new InvalidCastException("Unable to Read Xml Data for Abstract Type '" + typeof(AbstractType).Name +
"' because the Type specified in the XML differs ('" + type.Name + "').");
reader.ReadStartElement();
this.Data = (AbstractType)new
XmlSerializer(type).Deserialize(reader);
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
Type type = _data.GetType();
writer.WriteAttributeString("type", type.AssemblyQualifiedName);
new XmlSerializer(type).Serialize(writer, _data);
}
#endregion
}
}
সুতরাং, সেখান থেকে, আমরা কীভাবে এক্সএমএলসিরালাইজারকে ডিফল্টের চেয়ে আমাদের সিরিয়ালাইজারের সাথে কাজ করতে বলি? আমাদের অবশ্যই আমাদের প্রকারটি এক্সএমএল বৈশিষ্ট্য প্রকারের বৈশিষ্ট্যের মধ্যে পাস করতে হবে, উদাহরণস্বরূপ:
[XmlRoot("ClassWithAbstractCollection")]
public class ClassWithAbstractCollection
{
private List<AbstractType> _list;
[XmlArray("ListItems")]
[XmlArrayItem("ListItem", Type = typeof(AbstractXmlSerializer<AbstractType>))]
public List<AbstractType> List
{
get { return _list; }
set { _list = value; }
}
private AbstractType _prop;
[XmlElement("MyProperty", Type=typeof(AbstractXmlSerializer<AbstractType>))]
public AbstractType MyProperty
{
get { return _prop; }
set { _prop = value; }
}
public ClassWithAbstractCollection()
{
_list = new List<AbstractType>();
}
}
এখানে আপনি দেখতে পাচ্ছেন, আমাদের কাছে একটি সংগ্রহ এবং একক সম্পত্তি প্রকাশিত হচ্ছে এবং আমাদের যা করতে হবে তা হল প্রকারটি যুক্ত করা সহজ Xml ঘোষণা করার নামে প্যারামিটার! : ডি
দ্রষ্টব্য: আপনি যদি এই কোডটি ব্যবহার করেন তবে আমি সত্যিই চিৎকারের প্রশংসা করব। এটি আরও বেশি লোককে সম্প্রদায়ের দিকে চালিত করতে সহায়তা করবে :)
এখন, তবে উত্তরগুলির সাথে কী করবেন সে সম্পর্কে নিশ্চিত নন যেহেতু তাদের সকলেরই তাদের প্রো ও কনস রয়েছে। আমি যেগুলি দরকারী বলে মনে করি সেগুলি আমি আপডম করব (যারা ছিল না তাদের জন্য কোনও অপরাধ হবে না) এবং আমার কাছে রেপ পাওয়ার পরে এটি বন্ধ করে দেব :)
আকর্ষণীয় সমস্যা এবং সমাধান করার জন্য ভাল মজা! :)