एक मानक फॉर्मेटर का उपयोग करके मौजूदा वस्तुओं में वर्णन करें

नियमित deserialization .net हमेशा नई वस्तुओं का ग्राफ बनाता है। यह हमेशा सुविधाजनक नहीं होता है।



खोज ने तैयार जवाब नहीं दिया। प्रोटोबुफ़ और अन्य तृतीय-पक्ष धारावाहिकों का उपयोग करने के लिए सबसे आसान समाधान नहीं हैं, लेकिन यह हमेशा लागू नहीं होता है।

एक पूरे के रूप में कार्य मुश्किल नहीं है, और मेरा समाधान कुछ बकाया नहीं है, लेकिन दूसरी तरफ, उन लोगों के लिए जो पहली बार एक समान समस्या का सामना कर रहे हैं, यह आसान होगा।



क्रमांकन हमेशा की तरह किया जाता है। निम्नलिखित 2 कक्षाएं deserialization की समस्या को हल करेंगी।

[Serializable] public class RealObjectHelper : IObjectReference, ISerializable { Object m_realObject; virtual object getObject(ObjectId id) { //     , return id.GetObject(); } public RealObjectHelper(SerializationInfo info, StreamingContext context) { ObjectId id = (ObjectId)info.GetValue("ID", typeof(ObjectId)); m_realObject = getObject(id); if(m_realObject == null) return; Type t = m_realObject.GetType(); MemberInfo[] members = FormatterServices.GetSerializableMembers(t, context); List<MemberInfo> deserializeMembers = new List<MemberInfo>(members.Length); List<object> data = new List<object>(members.Length); foreach(MemberInfo mi in members) { Type dataType = null; if(mi.MemberType == MemberTypes.Field) { FieldInfo fi = mi as FieldInfo; dataType = fi.FieldType; } else if(mi.MemberType == MemberTypes.Property){ PropertyInfo pi = mi as PropertyInfo; dataType = pi.PropertyType; } try { if(dataType != null){ data.Add(info.GetValue(mi.Name, dataType)); deserializeMembers.Add(mi); } } catch (SerializationException) { //some fiels are missing, new version, skip this fields } } FormatterServices.PopulateObjectMembers(m_realObject, deserializeMembers.ToArray(), data.ToArray()); } public object GetRealObject( StreamingContext context ) { return m_realObject; } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] public void GetObjectData(SerializationInfo info, StreamingContext context) { } } public class RealObjectBinder: SerializationBinder { String assemVer; String typeVer; public RealObjectBinder(String asmName, String typeName) { assemVer = asmName; typeVer = typeName; } public override Type BindToType( String assemblyName, String typeName ) { Type typeToDeserialize = null; if ( assemblyName.Equals( assemVer ) && typeName.Equals( typeVer ) ) { return typeof(RealObjectHelper); } typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) ); return typeToDeserialize; } } 


Deserializing करते समय, आपको Binder स्थापित करने की आवश्यकता होती है, जो आपके मौजूदा ऑब्जेक्ट में deserialization के लिए एक आवरण बनाएगा।

  BinaryFormatter bf = new BinaryFormatter(null, context); bf.Binder = new RealObjectBinder(YourType.Assembly.FullName, YourType.FullName); bf.Deserialize(memStream); 

Source: https://habr.com/ru/post/In159855/


All Articles