Как указать System.Xml.Serialization.XmlSerializer сериализовать только базовый класс?

У меня есть массив объектов моего базового класса MyBase. Некоторые из этих объектов являются экземплярами производных классов, поэтому, когда я пытаюсь сериализовать этот массив с помощью System.Xml.Serialization.XmlSerializer, происходит сбой с жалобами на производные классы: System.InvalidOperationException: тип DerivedClass не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, неизвестные статически.

Я не хочу сериализовать производные классы и определенно не хочу помещать [XmlIgnore()] в производные классы (или [XmlInclude()] в базовый класс, если уж на то пошло)!

Есть ли способ указать XmlSerializer сериализовать базу только для такого члена, как этот?

[XmlElement("Items")]
public MyBase[] Items
{
    get
    {
        return items.ToArray();
    }
    set 
    {
        items = new HashSet<MyBase>(value);
    }
}

person l33t    schedule 12.04.2012    source источник
comment
Вы передаете тип конструктору xmlserializer?   -  person KristoferA    schedule 13.04.2012
comment
Я пробовал это, но не смог заставить это работать: List‹Type›derivedTypes = new List‹Type›(); foreach (элемент MyBase в элементах) {derifiedTypes.Add(item.GetType()); } Сериализатор XmlSerializer = новый XmlSerializer(typeof(RootItem), производныеТипы.ToArray());   -  person l33t    schedule 16.04.2012


Ответы (1)


Вы можете выполнить запрос Linq для коллекции элементов, фильтруя по типу:

[XmlElement("Items")]
public MyBase[] Items
{
    get
    {
        return items.Where(item => item.GetType() == typeof(MyBase)).ToArray();
    }
    set 
    {
        items = new HashSet<MyBase>(value);
    }
}
person John Holland    schedule 12.04.2012
comment
.OfType‹T› и/или .Cast‹T› тоже могут пригодиться - person KristoferA; 13.04.2012
comment
Спасибо. Однако не могу заставить его работать. Сериализатор продолжает пропускать мои элементы. - person l33t; 13.04.2012
comment
Хм, я думал, вы хотите, чтобы он сериализовал только непроизводные элементы MyBase? Этот фрагмент Linq намеренно пропускает элементы, которые не совсем соответствуют типу MyBase. - person John Holland; 16.04.2012
comment
После дальнейших размышлений вы могли бы реализовать конструктор глубокого копирования (или реализовать IClonable) в своем классе MyBase и просто выполнить return items.Select(item => new MyBase(item)).ToArray(); в методе доступа get для элементов. Если вы не хотите редактировать свой класс MyBase, вы можете реализовать один из многих внешних методов глубокого копирования, доступных через отражение. - person John Holland; 20.04.2012
comment
Пока мне не нужно делать дополнительную работу в каждом производном классе, я счастлив. Если я помещу все средства сериализации в базовый класс, а затем заполню список производных типов, которые будут переданы в конструктор XmlSerializer, он сработает. Это аналог вашего подхода? - person l33t; 21.04.2012