Как сериализовать массив базового класса, заполненного его подклассами, в XML? - PullRequest
2 голосов
/ 27 декабря 2010

Я пытаюсь сериализовать массив Test объектов, который содержит некоторые TestChild объекты.

public class Test
{
    public string SomeProperty { get; set; }
}

public class TestChild : Test
{
    public string SomeOtherProperty { get; set; }
}

class Program
{
    static void Main()
    {
        Test[] testArray = new[]
        {
            new TestChild { SomeProperty = "test1", SomeOtherProperty = "test2" },
            new TestChild { SomeProperty = "test3", SomeOtherProperty = "test4" },
            new TestChild { SomeProperty = "test5", SomeOtherProperty = "test6" },
        };

        XmlSerializer xs = new XmlSerializer(typeof(Test));

        using (XmlWriter writer = XmlWriter.Create("test.xml"))
            xs.Serialize(writer, testArray);
    }
}

Я получаю исключение InvalidOperationException, в котором говорится, что TestChild нельзя преобразовать в Test.

Это имеет смысл, но есть ли способ сделать это в любом случае?

Ответы [ 2 ]

1 голос
/ 27 декабря 2010

Самый простой способ - аннотировать класс так, чтобы сериализатор предвидел подкласс:

[XmlInclude(typeof(TestChild))]
public class Test
{
    public string SomeProperty { get; set; }
}

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

0 голосов
/ 27 декабря 2010

Вы можете указать известные типы, используя правильный конструктор , также вы сериализуете тестовый массив Test[], а не Test, следовательно, первый аргумент конструктора должен быть typeof(Test[]):

var xs = new XmlSerializer(typeof(Test[]), new Type[] { typeof(TestChild) });
...