簡體   English   中英

如何序列化和反序列化靜態引用對象?

[英]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()進行檢查。 原因是在您的代碼中:

  1. refObject是對A.Empty的引用(因此是同一對象)
  2. DeserializedObject不是副本; 它是一個新實例,因此是一個不同的對象

但是,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);
        }
    }
}

protobuf 和列表<object> - 如何序列化/反序列化?<div id="text_translate"><p> 我有一個List&lt;object&gt; ,其中包含不同類型的對象,例如整數、字符串和自定義類型。 所有自定義類型都經過 protobuf 調整。 我現在想做的是用 protobuf.net 序列化/反序列化這個列表。 到目前為止,我懷疑我必須顯式聲明每種類型,不幸的是,這些混合列表構造不可能做到這一點。 因為二進制格式化程序在做這些事情時沒有問題,我希望我錯過了一些東西,你可以幫助我。 所以我的問題是如何處理 protobuf.net 中的對象。</p></div></object>

[英]protobuf and List<object> - how to serialize / deserialize?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM