Когда методы с атрибутом [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]
шагах вызова.