Как использовать XmlSerializer для десериализации в существующий экземпляр? - PullRequest
6 голосов
/ 10 февраля 2009

Можно ли каким-то образом использовать XmlSerializer для десериализации своих данных в существующий экземпляр класса, а не в новый?

Это было бы полезно в двух случаях:

  1. Простое объединение двух файлов XML в один экземпляр объекта.
  2. Пусть сам объектный конструктор загружает данные из файла XML.

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

Ответы [ 4 ]

4 голосов
/ 10 февраля 2009

В принципе, вы не можете. XmlSerializer строго конструктивно. Единственная интересная вещь, которую вы можете сделать, чтобы настроить XmlSerializer, - это реализовать IXmlSerializable и делать все самостоятельно - не привлекательный вариант (и он все равно будет создавать новые экземпляры с конструктором по умолчанию и т. Д.).

Является ли xml строгим требованием? Если вы можете использовать другой формат, protobuf-net поддерживает объединение фрагментов в существующие экземпляры, например:

Serializer.Merge(source, obj);
1 голос
/ 10 февраля 2009

Я думаю, что вы на правильном пути с идеей Reflection.

Поскольку у вас, вероятно, в любом случае есть оболочка для операций XML, вы можете взять целевой объект, выполнить десериализацию обычно в новый объект, а затем сделать что-то похожее на клонирование, скопировав по одному только свойства, хранящие значения по умолчанию.

Это не должно быть таким сложным для реализации, и это будет выглядеть для потребителей из остальной части вашего приложения, как десериализация на месте.

0 голосов
/ 09 ноября 2016

Это не потокобезопасная вещь, которую можно сделать ... Но вы можете сделать:

[Serializable]
public class c_Settings
{
    static c_Settings Default;
    public static SetExistingObject(c_Settings def)
    {
        Default = def;
    }

    public string Prop1;
    public bool Prop2;

    public c_Settings()
    {
        if (Default == null)
            return;
        MemberInfo[] members = FormatterServices.GetSerializableMembers(typeof(c_Settings));
        FormatterServices.PopulateObjectMembers(this, members, FormatterServices.GetObjectData(Default, members));
    }
}

Таким образом, вы передаете свой объект десериализатору, а десериализатор перезаписывает только то, что написано в .xml.

0 голосов
/ 11 февраля 2009

Я столкнулся с той же проблемой несколько недель назад.

Я поместил метод Deserialize (сериализованная строка) в интерфейс ISelfSerializable, который реализовал мой класс сущностей. Я также убедился, что интерфейс заставил класс иметь конструктор по умолчанию.

На своей фабрике я создал объект такого типа, а затем десериализовал строку в него.

...