Сериализация XML.NET и наследование

Хорошей ссылкой на процессе разработки, который сохраняет стабильность соединительной линии и действительно все работает в ответвлениях, является Divmod Окончательная Качественная Система Разработки . Быстрая сводка:

  • Всей сделанной работе нужно было связать билет с ним
  • А, новое ответвление создается для каждого билета, где работа для того билета сделана
  • , Изменения от того ответвления не объединяются назад в соединительную линию магистрали, не будучи рассмотренным другим участником проекта

, Они используют SVN для этого, но это могло легко быть сделано с любой из распределенных систем управления версиями.

11
задан John Saunders 10 November 2009 в 16:42
поделиться

6 ответов

Вы можете попробовать использовать DataContractSerializer :

public interface A
{
}

public class B : A
{
}

public class C : A
{
}

class Program
{
    static void Main(string[] args)
    {
        List<A> list = new List<A>(new A[] { new B(), new C() });
        var serializer = new DataContractSerializer(
            list.GetType(), new[] { typeof(B), typeof(C) });

        var sb = new StringBuilder();
        using (var stringWriter = new StringWriter(sb))
        using (var writer = XmlWriter.Create(stringWriter))
        {
            serializer.WriteObject(writer, list);
        }

        using (var stringReader = new StringReader(sb.ToString()))
        using (var reader = XmlReader.Create(stringReader))
        {
            list = (List<A>)serializer.ReadObject(reader);
        }

    }
}
4
ответ дан 3 December 2019 в 06:21
поделиться

Предполагая, что вы используете встроенную сериализацию XML .net, вам следует взглянуть на следующий атрибут:

System.Xml.Serialization.XmlIncludeAttribute

Он позволяет указать сериализатору включать другие типы при сериализации / десериализации.

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

6
ответ дан 3 December 2019 в 06:21
поделиться

Я бы использовал абстрактный класс вместо интерфейса (поскольку нельзя сериализовать тип интерфейса), тогда вместо жесткого кодирования типа с использованием атрибута XmlInclude я бы добавил известные типы для XmlSerializer в методах Serial и Deserialize, например:

    string listXml = Serialize<List<A>>(ListA, new Type[] { typeof(B), typeof(C) });

    List<IA> NewList = Deserialize<List<A>>(listXml, new Type[] { typeof(B), typeof(C) });

    private static T Deserialize<T>(string Xml, Type[] KnownTypes)
    {
        XmlSerializer xs = new XmlSerializer(typeof(T),KnownTypes);

        StringReader sr = new StringReader(Xml);
        return (T)xs.Deserialize(sr);
    }

    private static string Serialize<T>(Object obj, Type[] KnownTypes)
    {
        StringBuilder sb = new StringBuilder();
        using (StringWriter sw = new StringWriter(sb))
        {
            XmlSerializer xs = new XmlSerializer(typeof(T), KnownTypes);

            xs.Serialize(sw, obj);
        }
        return sb.ToString();
    }
5
ответ дан 3 December 2019 в 06:21
поделиться

Да, но вам нужно поиграть с атрибутами XmlElement, XmlRoot и XmlArray. Каждому типу требуется собственное имя элемента.

РЕДАКТИРОВАТЬ: Пример кода. Все классы являются производными от общего базового класса.

Вот пример кода:

[XmlRoot(ElementName="Root")]
public sealed class SomeObject
{

    private BaseObject _Object;

    [XmlElement(Type=typeof(App.Projekte.Projekt), ElementName="Projekt")]
    [XmlElement(Type=typeof(App.Projekte.Task), ElementName="Task")]
    [XmlElement(Type=typeof(App.Projekte.Mitarbeiter), ElementName="Mitarbeiter")]
    public BaseObject Object
    {
        get
        {
            return _Object;
        }
        set
        {
            _Object = value;
        }
    }
}

РЕДАКТИРОВАТЬ: удалить атрибут сериализации, так как он не нужен (но необходим в моем проекте, откуда взят код)

4
ответ дан 3 December 2019 в 06:21
поделиться

Для вашего случая создайте абстрактный класс, который реализует ваш интерфейс, например:

abstract class Abs : A

, а затем наследуйте свои классы от Abs

public class B : Abs
public class C : Abs

и Список списка;

теперь используйте XmlIncludeAttribute для добавления ваших типов в массив типов XmlSerializer.

0
ответ дан 3 December 2019 в 06:21
поделиться

XmlSerializer не работает с интерфейсами. Таким образом, вы можете:

преобразовать интерфейс в абстрактный класс, а затем использовать для него XmlIncludeAttribute или указать KnownTypes для XmlSerializer

или

реализовать IXmlSerializable для родительского тип

или

Рассмотрите возможность использования DataContractSerializer из .NET 3.0

0
ответ дан 3 December 2019 в 06:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: