2

次のシナリオのように動作する .NET (逆) シリアル化の舞台裏で何が起こっているのでしょうか? (これは、私のセットアップを説明するためのテスト アプリです。)

NameValueCollection プロパティを持つクラスがあります。

[Serializable]
public class MyClassWithNVC
{
    public NameValueCollection NVC { get; set; }
}

次に、別のクラスに含まれています。

[Serializable]
class Wrapper : ISerializable
{
    public MyClassWithNVC MyClass { get; private set; }

    public Wrapper()
    {
        MyClass = new MyClassWithNVC
                      {
                          NVC = new NameValueCollection
                                    {
                                        {"TestKey", "TestValue"}
                                    }
                      };
    }

    public Wrapper(SerializationInfo info, StreamingContext context)
    {
        MyClass = info.GetValue("MyClass", typeof(MyClassWithNVC)) as MyClassWithNVC;

        if(MyClass.NVC == null)
        {
            Console.WriteLine("NVC is null inside Wrapper's ctor.");
        }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("MyClass", MyClass);
    }
}

私のテストプログラムは以下の通りです:

class Program
{
    static void Main(string[] args)
    {
        using(MemoryStream ms = new MemoryStream())
        {
            Wrapper wrapper = new Wrapper();
            new BinaryFormatter().Serialize(ms, wrapper);

            ms.Seek(0, SeekOrigin.Begin);

            Wrapper loaded = new BinaryFormatter().Deserialize(ms) as Wrapper;
            if(loaded.MyClass.NVC.Count == 1 && loaded.MyClass.NVC[0] == "TestValue")
            {
                Console.WriteLine("NVC is not null after Wrapper's ctor and has the correct value.");
            }
        }

        Console.ReadKey();
    }
}

実行すると、コンソールに次のように表示されます。

NVC は Wrapper の ctor 内で null です。

NVC は Wrapper の ctor の後に null ではなく、正しい値を持っています。

何が起きてる?NameValueCollection は明らかにデフォルトのシリアル化でそれ自体を逆シリアル化できますが、逆シリアル化が遅延し、Wrapper のコンストラクターの GetValue() 呼び出しで発生しないのはなぜですか?

4

1 に答える 1

2

Deserialize メソッドがどのように実装されているかを正確に知ることなく、少し掘り下げようとしました。

最初に ISerializable コードの実装を実行するようです。すべてのカスタム コードが完了すると、自動的にシリアル化されたすべてのオブジェクト (サンプルの MyClassWithNVC クラスなど) が逆シリアル化されます。

MyClassWithNVC継承を許可するISerializableと、カスタムのデシリアライゼーション コードが実行され、MyClass.NVC は Wrapper デシリアライザー メソッドで NULL ではありません。

したがって、これは特定の動作でNameValueCollectionはなく、自動的にシリアル化されるプロパティです。

于 2010-02-22T19:33:14.483 に答える