我只注意到在二進制序列化一個奇怪的現象:當我反序列化的字典在我的課,並嘗試一些立即添加到它,我得到一個錯誤,因爲它不是完全初始化:奇怪的反序列化的錯誤,子對象不能完全反序列化
[Serializable]
class Foo : ISerializable
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public Foo(SerializationInfo info, StreamingContext context)
{
Dict = (Dictionary<int, string>)info.GetValue("Dict", typeof(Dictionary<int, string>));
Dict.Add(99, "test"); // Error here
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Dict", Dict);
}
}
在那裏我將數據添加到字典中的線,我得到一個NullReferenceException
,但Dict
屬性不爲null:它被實例化,但不初始化(所有的字段都爲0或空)。我懷疑它只是用FormatterServices.GetUninitializedObject
創建的,但實際上並沒有反序列化。
據我所知,在這一點上,也許它不是假設被完全初始化。所以我嘗試了另一種方法,通過實現IDeserializationCallback
接口。 MSDN說:
將當前接口實現爲對象圖的反序列化完成時調用的方法的支持的一部分。
如果一個對象需要在其子對象執行代碼,它可延緩 這個動作,實現IDeserializationCallback,並執行代碼 只有當它被稱爲回該接口上
所以它似乎正是我所需要的,並且我期望我的字典在被調用時被完全初始化...但我得到同樣的錯誤!
[Serializable]
class Foo : IDeserializationCallback
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public void OnDeserialization(object sender)
{
Dict.Add(99, "test"); // Error here
}
}
由於IDeserializationCallback
被設計爲在子對象執行代碼,我希望孩子反對在這一點上完全初始化。請注意,如果我在字典上手動調用OnDeserialize
,它可以正常工作,但不知何故,我認爲我不應該這麼做...
此行爲是否正常?任何人都可以解釋這裏發生了什麼?
我已經檢查了這一點,和事件'[OnDeserialized]'屬性沒有幫助。此外,我已經檢查.NET的源代碼,並基於他們的一切應該被初始化,當任一的'[OnDeserialized]'或'IDeserializationCallback.OnDeserialization'稱爲 –
OnDeserialization當整個對象圖反序列化被調用。我懷疑真正的問題是位於序列化代碼中。從這裏看不到它。 –