Когда методы с атрибутом `[OnDeserializing]` вызываются в C#? - PullRequest
0 голосов
/ 14 марта 2020

Когда методы с атрибутом [OnDeserializing] вызываются в C#?

Я знаю (из CLR через C# книгу), что шаги по десериализации Объект в C#:

1 Get Type Форматировщик считывает идентификатор сборки и полное имя типа из потока. Если сборка в данный момент не загружена в домен приложений, она загружается (как описано ранее). Если сборка не может быть загружена, выдается исключение SerializationException, и объект не может быть десериализован. Если сборка загружена, средство форматирования передает идентификационную информацию сборки и полное имя типа методу FormatterServices’s stati c GetTypeFromAssembly: public static Type GetTypeFromAssembly(Assembly assem, String name); Этот метод возвращает объект System.Type, указывающий тип объекта, который используется. десериализовано.

2 Получить неинициализированный объект Форматировщик вызывает метод FormatterServices’s stati c GetUninitializedObject: public static Object GetUninitializedObject(Type type); Этот метод выделяет память для нового объекта, но не вызывает конструктор для объекта. Однако все байты объекта инициализируются нулем или 0.

3 Get MemberInfos Форматер теперь создает и инициализирует массив MemberInfo, как это было раньше, вызывая FormatterServices’s GetSerializableMembers метод. Этот метод возвращает набор полей, которые были сериализованы и должны быть десериализованы.

4 Получить значения полей Форматировщик создает и инициализирует массив Object из данных, содержащихся в потоке .

5 Установка значений полей Ссылка на вновь выделенный объект, массив MemberInfo и параллельный массив Object значений полей передаются в FormatterServices’ stati c PopulateObjectMembers method: public static Object PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data); Этот метод перечисляет массивы, инициализируя каждое поле соответствующим значением. На данный момент объект был полностью десериализован.

Будут ли вызваны методы с атрибутом [OnDeserializing] между 4-м и 5-м шагами? Я не смог найти четкого ответа на вопрос ни в документации MSDN, ни в книге, ни по поиску.

ОБНОВЛЕНИЕ

После комментариев к вопрос Я попробовал следующий код ( fiddle ):

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
class A
{
    public int i;
    public string s;

    [OnDeserializing]
    [OnDeserialized]
    public void foo(StreamingContext context)
    {
        var stop = 0;
    }
}

public sealed class Program
{
    public static void Main(string[] args)
    {
        var a = new A();
        a.i = 47;
        a.s = "foo47";

        using(var stream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(stream, a);
            stream.Position = 0;
            var ad = formatter.Deserialize(stream);
        }
    }
}

Я добавил точку останова на строку var stop = 0; и убедился, что метод foo вызывается дважды. Один раз для [OnDeserializing] и один раз для [OnDeserialized]. В первом случае значения поля экземпляра равны i = 0, s = null, а во втором случае значения равны i = 47, s = "foo47". Но я не уверен, как я могу сделать вывод о [OnDeserializing] шагах вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...