2012-01-13 2 views
10

Редактировать Этот код должен показать всю проблему:Почему XmlSerializer сериализует абстрактные классы, но не интерфейсы?

[XmlInclude(typeof(AThing1))] 
public abstract class AThing 
{ 
    public abstract string Name { get; set; } 
} 

[XmlInclude(typeof(IThing1))] 
public interface IThing 
{ 
    string Name { get; set; } 
} 

public class AThing1 : AThing 
{ 
    public override string Name { get; set; } 
} 

public class IThing1 : IThing 
{ 
    public string Name { get; set; } 
} 

List<AThing> aThings = new List<AThing>(new AThing[] { new AThing1() { Name = "Bob" } }); 
List<IThing> iThings = new List<IThing>(new IThing[] { new IThing1() { Name = "Bob" } }); 

public void Test() 
{ 
    using (StringWriter sw = new StringWriter()) 
    { 
     XmlSerializer aSerializer = new XmlSerializer(typeof(List<AThing>)); 
     aSerializer.Serialize(sw, aThings); 
     string text = sw.ToString(); 
    } 

    using (StringWriter sw = new StringWriter()) 
    { 
     // This line will throw "Cannot serialize interface IThing.": 
     XmlSerializer iSerializer = new XmlSerializer(typeof(List<IThing>));  
     iSerializer.Serialize(sw, iThings); 
     string text = sw.ToString(); 
    } 
} 

text Первый порожденную aSerializer будет:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfAThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <AThing xsi:type="AThing1"> 
    <Name>Bob</Name> 
    </AThing> 
</ArrayOfAThing> 

Я не вижу, почему не может iSerializer сделать это:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfIThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <IThing xsi:type="IThing1"> 
    <Name>Bob</Name> 
    </IThing> 
</ArrayOfIThing> 

вместо того, чтобы исключать исключение.

+0

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

+0

@JohnSaunders: Смотрите мое обновление. Думаю, теперь должно быть ясно. – Juan

+0

Для записи, какое полное исключение вы получаете? –

ответ

5

вы можете сериализовать интерфейс, но не так просто, как классы:

http://ventspace.wordpress.com/2010/02/20/how-to-serialize-interfaces-in-net/

, но ответить на ваш вопрос, у меня есть 2 предположения об этом:

Первая причина с практической стороны; Семантика сериализации интерфейса немного размыта. Как вы думаете, сериализатор должен сериализоваться при передаче ссылки на интерфейс? Если вы только сериализуете свойства интерфейса, ваш десериализовать, то может завершиться с на половину неинициализированного объекта. Нельзя сказать, что бы это сделало с вашей заявкой.

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

Второй из них соответствует заявленной цели XmlSerializer. Несмотря на то, что вводящее в заблуждение имя XML-сериализация в .NET Framework действительно представляет собой технологию привязки данных с основным намерением сопоставить типы данных MXL, определенные в схемах XSD для типов .NET. Определение XSD знает об абстрактных базовых классах , но поскольку он ориентирован на данные, ничего не знает о интерфейсах . Имея это в виду, есть небольшая мотивация для поддержки интерфейсов в XmlSerializer.

2

XmlSerializer не сериализует абстрактные классы. Он сериализует один из нескольких классов бетон.

+2

Ну, почему же он не может сделать то же самое с интерфейсами? – Juan

+0

Конкретные классы, на которые я ссылаюсь, это те, которые вы ссылаетесь в 'XmlInclude' –

+8

Я понимаю, о чем вы говорите, но не понимаете, какова ваша точка.Почему «XmlSerializer» не может сериализовать конкретные классы, реализующие интерфейс так же, как он может сериализовать конкретные классы, реализующие абстрактный класс, где объект, который будет сериализован, представлен в списке, объявленном как примеры, которые я дал в моем вопросе? – Juan

Смежные вопросы