[英]How to serialize & deserialize static reference object?
我想使用BinaryFormatter序列化和反序列化一個對象(該對象具有引用)。
我期望'DeserializedObject.Equals(A.Empty)'與以下代碼相同。 但是結果卻不同。
為了“ DeserializedObject == A.Empty”,如何使用序列化/反序列化?
[Serializable]
public class A
{
private string ID = null;
private string Name = null;
public A()
{ }
public static A Empty = new A()
{
ID = "Empty",
Name = "Empty"
};
}
class Program
{
static void Main(string[] args)
{
A refObject = A.Empty; // Add reference with static object(Empty)
A DeserializedObject;
//Test
//before serialization, refObject and A.Empty is Same!!
if(refObject.Equals(A.Empty))
{
Console.WriteLine("refObject and A.Empty is the same ");
}
//serialization
using (Stream stream = File.Create("C:\\Users\\admin\\Desktop\\test.mbf"))
{
BinaryFormatter bin = new BinaryFormatter();
bin.Serialize(stream, refObject);
}
//Deserialization
using (Stream stream = File.Open("C:\\Users\\admin\\Desktop\\test.mbf", FileMode.Open))
{
BinaryFormatter bin = new BinaryFormatter();
DeserializedObject = (A)bin.Deserialize(stream);
}
//compare DeserializedObject and A.Empty again.
//After deserialization, DeserializedObject and A.Empty is Different!!
if (DeserializedObject.Equals(A.Empty))
{
Console.WriteLine("Same");
}
else
Console.WriteLine("Different");
}
}
這是因為它們是不同的對象! 您可以通過打印其GetHashCode()進行檢查。 原因是在您的代碼中:
但是,DeserializedObject應該包含相同的值(ID和Name)。 注意,refObject.ID將與A.Empty.ID是同一對象; DeserializedObject.ID不會,盡管它應該包含相同數據(的副本)。
如果您只是在測試反序列化是否正常,請測試DeserializedObject和A.Empty包含的值是否相同。
如果您有具有代表型(標准值的一個或多個全局單不可變型A.Empty
你的情況),您可以實現IObjectReference
接口,使BinaryFormatter
替代類型的反序列化的情況下,與合適的,相當於全球單身人士。 從而:
[Serializable]
public class A : IObjectReference
{
private string ID = null;
private string Name = null;
public A()
{ }
public static A Empty = new A()
{
ID = "Empty",
Name = "Empty"
};
#region IObjectReference Members
object IObjectReference.GetRealObject(StreamingContext context)
{
if (this.GetType() == Empty.GetType() // Type check because A is not sealed
&& this.ID == Empty.ID
&& this.Name == Empty.Name)
return Empty;
return this;
}
#endregion
}
並且,要測試:
public class TestClass
{
public static void Test()
{
A refObject = A.Empty; // Add reference with static object(Empty)
Test(refObject, true);
A dummy = new A(); // No global singleton for this one.
Test(dummy, false);
}
private static void Test(A refObject, bool shouldBeEqual)
{
Console.WriteLine(string.Format("refObject and A.Empty are {0}.", object.ReferenceEquals(refObject, A.Empty) ? "identical" : "different"));
var binary = BinaryFormatterHelper.ToBase64String(refObject);
var DeserializedObject = BinaryFormatterHelper.FromBase64String<A>(binary);
Console.WriteLine(string.Format("DeserializedObject and A.Empty are {0}.", object.ReferenceEquals(DeserializedObject, A.Empty) ? "identical" : "different"));
Debug.Assert(object.ReferenceEquals(refObject, A.Empty) == object.ReferenceEquals(DeserializedObject, A.Empty)); // No assert
Debug.Assert(shouldBeEqual == object.ReferenceEquals(refObject, DeserializedObject)); // No assert
}
}
public static class BinaryFormatterHelper
{
public static string ToBase64String<T>(T obj)
{
using (var stream = new MemoryStream())
{
new BinaryFormatter().Serialize(stream, obj);
return Convert.ToBase64String(stream.GetBuffer(), 0, checked((int)stream.Length)); // Throw an exception on overflow.
}
}
public static T FromBase64String<T>(string data)
{
return FromBase64String<T>(data, null);
}
public static T FromBase64String<T>(string data, BinaryFormatter formatter)
{
using (var stream = new MemoryStream(Convert.FromBase64String(data)))
{
formatter = (formatter ?? new BinaryFormatter());
var obj = formatter.Deserialize(stream);
if (obj is T)
return (T)obj;
return default(T);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.