Что происходит за кулисами во время десериализации коллекции NameValueCollection? - PullRequest
2 голосов
/ 22 февраля 2010

Что происходит за кулисами в сериализации .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 является нулевым внутри ctor Wrapper.

NVC не равен нулю после ctor Wrapper и имеет правильное значение.

Что здесь происходит? Коллекция NameValueCollection, очевидно, способна десериализовать себя с помощью сериализации по умолчанию, но почему эта десериализация задерживается и не происходит при вызове GetValue () в конструкторе Wrapper?

1 Ответ

2 голосов
/ 22 февраля 2010

Я попытался немного покопаться в методе десериализации, не выяснив, как именно он реализован.

Кажется, он сначала запустит реализацию кода ISerializable. Как только весь пользовательский код будет завершен, он десериализует все автоматически сериализованные объекты (например, ваш класс MyClassWithNVC в образце).

Если вы разрешите MyClassWithNVC наследовать от ISerializable, тогда он выполнит ваш пользовательский код десериализации, и MyClass.NVC не будет иметь значение NULL в методе десериализации Wrapper.

Так что это не специфическое поведение NameValueCollection, а любое свойство, которое автоматически сериализуется.

...