Переопределенная десериализация в XmlSerializer никогда не вызывается - PullRequest
1 голос
/ 06 марта 2011

Я медленно чувствую, как мое здравомыслие изнашивается по краям, пока мой разум медленно истощается.

Я хочу расширить XmlSerializer, который по некоторым причинам не поддерживает уведомления десериализации.

У меня естьследующий код:

public class NotificationXmlSerializer : XmlSerializer
{
    public NotificationXmlSerializer(Type type)
        : base(type)
    { 
    }

    protected override object Deserialize(XmlSerializationReader reader)
    {
        var x = base.Deserialize(reader);
        var methods = x.GetType().GetMethods().Where(method => method.GetCustomAttributes(true).Any(attr => attr is OnDeserializedAttribute));

        return x;
    }
}

И используйте его следующим образом:

    using (MemoryStream fs = new MemoryStream())
    {
        var x = new NotificationXmlSerializer(typeof(int));
        x.Serialize(fs, 5);
        fs.Seek(0, SeekOrigin.Begin);
        var y = x.Deserialize(fs);
    }

Однако, если я добавлю точку прерывания в переопределение десериализации, он никогда не будет достигнут!Даже если я намеренно добавляю исключение, функция программы нормальная, поэтому я уверен, что она никогда не срабатывает.

Почему они позволили бы мне переопределить внутренний метод Deserialize, не позволяя мне что-либо повлиять на него?

Что я делаю не так?

С уважением, Макс

1 Ответ

5 голосов
/ 06 марта 2011

Во-первых, как утверждает MSDN, метод предназначен для внутренних целей:

Этот API поддерживает инфраструктуру .NET Framework и не предназначен для использования непосредственно из вашего кода.

Во-вторых, если вы посмотрите на XmlSerializer с помощью Reflector, вы обнаружите единственное место, откуда вызывается этот метод.Упрощенный поток управления:

public object Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
{
    …
    try
    {
        if (this.primitiveType != null)
        {
            …
            return this.DeserializePrimitive(xmlReader, events);
        }
        if ((this.tempAssembly == null) || this.typedSerializer)
        {
            XmlSerializationReader reader = …
            try
            {
                return this.Deserialize(reader);
…

Несмотря на то, что этот метод (Deserialize(XmlReader, string, XmlDeserializationEvents)) вызывается из всех других методов Deserialize, это не означает, что поток управления должен заканчиваться на Deserialize(XmlSerializationReader).

Мой совет: найдите справочный источник для XmlSerializer, изучите поведение и либо решите свою проблему другим способом, либо отрегулируйте внешние условия так, как называется ваше переопределение.Лично я бы не стал полагаться на переопределение метода.В итоге вы получите более стабильное поведение и , предотвращающее проблемы совместимости с будущими версиями фреймворка.

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