17

少なくとも私の予想では、.NETのバイナリシリアル化で奇妙な動作に遭遇しました。

ロードされたのすべてのアイテムはDictionary、コールバック後に親に追加されOnDeserializationます。対照的Listに、他の方法を行います。これは、たとえば辞書アイテムにデリゲートを追加する必要がある場合など、実際のリポジトリコードでは非常に煩わしい場合があります。サンプルコードを確認し、アサートを確認してください。

それは正常な動作ですか?

[Serializable]
public class Data : IDeserializationCallback
{
    public List<string> List { get; set; }

    public Dictionary<string, string> Dictionary { get; set; }

    public Data()
    {
        Dictionary = new Dictionary<string, string> { { "hello", "hello" }, { "CU", "CU" } };
        List = new List<string> { "hello", "CU" };
    }

    public static Data Load(string filename)
    {
        using (Stream stream = File.OpenRead(filename))
        {
            Data result = (Data)new BinaryFormatter().Deserialize(stream);
            TestsLengthsOfDataStructures(result);

            return result;
        }
    }

    public void Save(string fileName)
    {
        using (Stream stream = File.Create(fileName))
        {
            new BinaryFormatter().Serialize(stream, this);
        }
    }

    public void OnDeserialization(object sender)
    {
        TestsLengthsOfDataStructures(this);
    }

    private static void TestsLengthsOfDataStructures(Data data)
    {
        Debug.Assert(data.List.Count == 2, "List");
        Debug.Assert(data.Dictionary.Count == 2, "Dictionary");
    }
}
4

3 に答える 3

10

Dictionary<TKey, TValue>はい、デシリアライゼーションの厄介な癖を発見しました。OnDeserialization()辞書のメソッドを手動で呼び出すことで回避できます。

public void OnDeserialization(object sender)
{
    Dictionary.OnDeserialization(this);
    TestsLengthsOfDataStructures(this);
}

ちなみに、 の[OnDeserialized]代わりに属性を使用することもできIDeserializationCallbackます。

[OnDeserialized]
public void OnDeserialization(StreamingContext context)
{
    Dictionary.OnDeserialization(this);
    TestsLengthsOfDataStructures(this);
}
于 2009-01-19T10:43:31.147 に答える
8

問題を再現できます。Google を調べてみると、http: //connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx ?FeedbackID=94265 が見つかりましたが、まったく同じ問題かどうかはわかりませんが、かなり似ているようです。

編集:

このコードを追加すると問題が解決したのではないでしょうか?

    public void OnDeserialization(object sender)
    {
            this.Dictionary.OnDeserialization(sender);
    }

徹底的にテストする時間はないので、Marc に勝って答えたいと思います ;-)

于 2009-01-19T10:42:37.153 に答える
4

興味深い...情報として、属性ベースのアプローチ(下記)で試してみましたが、同じように動作します...非常に興味深いです! 私はそれを説明することはできません-私はただ再現を確認し、[OnDeserialized]動作について言及するために返信しています:

[OnDeserialized] // note still not added yet...
private void OnDeserialized(StreamingContext context) {...}

編集 -ここで「接続」の問題が見つかりました。コールバックに追加してみてください:

Dictionary.OnDeserialization(this);
于 2009-01-19T10:42:18.183 に答える