मैं कुछ ऑब्जेक्ट्स के Lazy
Collection
वाले किसी ऑब्जेक्ट को सीरियललाइज़ और डीसिरियलाइज़ करना चाहता हूं।आलसी ऑब्जेक्ट को deserialize करने में सक्षम नहीं
आम तौर पर सबकुछ ठीक से काम करता है लेकिन, यदि धारावाहिकरण के लिए उपयोग की जाने वाली कक्षाओं के नामस्थान बदल दिए जाते हैं, तो यह समस्या होती है।
मैंने deserializing जबकि सही कक्षाओं को इंगित करने के लिए SerializationBinder
लिखा है। लेकिन किसी कारण से, मुझे deserialized मूल्य नहीं मिल रहा है।
निम्नलिखित कोड स्निपेट मुझे जो समस्या मिल रही है उसे बताती है;
क्रमबद्धता के लिए इस्तेमाल किया क्लास:
namespace ConsoleApplication14
{
[Serializable]
public class MyInnerClass : ISerializable
{
private string _stringInInnerClassKey = "StringInInnerClass";
public string StringInInnerClass { get; set; }
public MyInnerClass() { }
private MyInnerClass(SerializationInfo info, StreamingContext context)
{
StringInInnerClass = info.GetString(_stringInInnerClassKey);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(_stringInInnerClassKey, StringInInnerClass);
}
}
[Serializable]
public class MyOuterClass : ISerializable
{
private string _collectionOfObjKey = "CollectionOfInnerObj";
public Lazy<Collection<MyInnerClass>> CollectionOfInnerObj { get; set; }
private MyOuterClass(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException("serializationInfo");
CollectionOfInnerObj =
(Lazy<Collection<MyInnerClass>>)
info.GetValue(_collectionOfObjKey, typeof(Lazy<Collection<MyInnerClass>>));
}
public MyOuterClass() { }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException();
info.AddValue(_collectionOfObjKey, CollectionOfInnerObj, typeof(Lazy<Collection<MyInnerClass>>));
}
}
}
ही वर्गों के ऊपर, Deserialization के लिए उपयोग किया जाता है, लेकिन केवल नाम स्थान काम करने के लिए ConsoleApplication14.OtherNamespace
परिवर्तित करने के लिए इस तरह के Deserialization के लिए मैं निम्नलिखित SerializationBinder
का इस्तेमाल किया है कक्षा:
public class MyBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (assemblyName.Equals(
"ConsoleApplication14, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"))
{
if (typeName.Equals("ConsoleApplication14.MyOuterClass"))
return typeof(ConsoleApplication14.OtherNamespace.MyOuterClass);
if (typeName.Equals("ConsoleApplication14.MyInnerClass"))
return typeof(ConsoleApplication14.OtherNamespace.MyInnerClass);
}
if (assemblyName.Equals("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"))
{
if (typeName.Equals(
"System.Collections.ObjectModel.Collection`1[[ConsoleApplication14.MyInnerClass, ConsoleApplication14, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"))
return typeof(Collection<ConsoleApplication14.OtherNamespace.MyInnerClass>);
if (typeName.Equals(
"System.Collections.Generic.List`1[[ConsoleApplication14.MyInnerClass, ConsoleApplication14, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"))
return typeof(List<ConsoleApplication14.OtherNamespace.MyInnerClass>);
if (typeName.Equals(
"System.Lazy`1[[System.Collections.ObjectModel.Collection`1[[ConsoleApplication14.MyInnerClass, ConsoleApplication14, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"))
return typeof(Lazy<Collection<ConsoleApplication14.OtherNamespace.MyInnerClass>>);
//I THINK, MAYBE THIS 'IF' CONDITION IS THE PROBLEM, BUT DONT KNOW HOW TO FIX THIS.
if (typeName.Equals(
"System.Lazy`1+Boxed[[System.Collections.ObjectModel.Collection`1[[ConsoleApplication14.MyInnerClass, ConsoleApplication14, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"))
return typeof(Lazy<Collection<ConsoleApplication14.OtherNamespace.MyInnerClass>>);
}
return Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
}
}
क्रमबद्धता और MyCustomClass
की वस्तु की Deserialization:
public static void Main(string[] args)
{
//----------------Object Creation----------------------
var objToSerialize = new MyOuterClass
{
CollectionOfInnerObj =
new Lazy<Collection<MyInnerClass>>(
() => new Collection<MyInnerClass>
{
new MyInnerClass
{
StringInInnerClass = "a"
},
new MyInnerClass
{
StringInInnerClass = "aa"
},
})
};
//------------------------------------------------------
//---------------------Serialization---------------------
using (var stream = File.Create("E:\\tempFile.tmp"))
{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, objToSerialize);
stream.Close();
}
//------------------------------------------------------
//-------------------DeSerialization--------------------
using (var stream = File.OpenRead("E:\\tempFile.tmp"))
{
var binaryFormatter = new BinaryFormatter {Binder = new MyBinder()};
var objOfOtherNamespaceClass = (OtherNamespace.MyOuterClass) binaryFormatter.Deserialize(stream);
//Getting NullReferenceException when Value property of objOfOtherNamespaceClass.CollectionOfInnerObj is called
foreach (OtherNamespace.MyInnerClass stringVal in objOfOtherNamespaceClass.CollectionOfInnerObj.Value)
Console.WriteLine(stringVal.StringInInnerClass);
stream.Close();
}
//-----------------------------------------------------
}
मैं NullReferenceException
हो रही है जब deserialized लेज़ी वस्तु की Value
संपत्ति कहा जाता है। (यानी जब objOfOtherNamespaceClass.CollectionOfInnerObj.Value
कहा जाता है)
कृपया मुझे इस समस्या को हल करने में मदद ...
मुझे याद है, आईएसरोगेट के साथ बाइनरीफॉर्मेटर में एक बग था जब सर्कुलर निर्भरता (डी) क्रमबद्ध ग्राफ में थी और इसे ठीक करने का कोई इरादा नहीं था। मुझे यकीन नहीं है, लेकिन यह व्यवहार समान दिखता है। – TcKs