如何序列化和反序列化静态参考对象? [英] How to serialize & deserialize static reference object?

查看:208
本文介绍了如何序列化和反序列化静态参考对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要序列化&使用BinaryFormatter反序列化对象(该对象具有引用).

i want to serialize & deserialize a object (this object has reference) using BinaryFormatter.

我期望'DeserializedObject.Equals(A.Empty)'与以下代码相同. 但是结果是不同的.

i have expected that 'DeserializedObject.Equals(A.Empty)' is same to below code. but, a result is different.

为了"DeserializedObject == A.Empty",如何使用序列化/反序列化?

in order to 'DeserializedObject == A.Empty', how to use serialize/deserialize ?

[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");
    }
}

推荐答案

如果您的不可变类型具有一个或多个表示该类型标准值的全局单例(在您的情况下为A.Empty),则可以实现 IObjectReference 接口,并使BinaryFormatter用适当的等效全局单例替换类型的反序列化实例.因此:

If you have an immutable type which has one or more global singletons that represent standard values of the type (A.Empty in your case), you can implement the IObjectReference interface and make BinaryFormatter replace deserialized instances of the type with the appropriate, equivalent global singleton. Thus:

[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);
        }
    }
}

这篇关于如何序列化和反序列化静态参考对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆