XmlSerialization и интерфейсы

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

Когда я десериализуюсь и приведу обратно к интерфейсу, некоторые свойства будут нулевыми. Но если я приведу обратно к конкретному типу, то же свойство будет иметь значение?

Итак, учитывая этот XML (сокращенно для краткости):

<Page>
  <ComponentPresentations>
    <ComponentPresentation>
      <Component>
        <Categories>
          <Category>
            <Id>tcm:35-540-512</Id>

Десериализация с

var serializer = new XmlSerializer(typeof(Page));
page = (IPage)serializer.Deserialize(reader);

page.ComponentPresentations[0].Component.Categories <-- is null

Но если я приведу обратно к типу,

var serializer = new XmlSerializer(typeof(Page));
page = (Page)serializer.Deserialize(reader);

page.ComponentPresentations[0].Component.Categories <-- is not null!

Тип страницы предоставляет свойство интерфейса Categories и неинтерфейсное свойство - я предполагаю обойти проблему интерфейса сериализации.

public List<Category> Categories { get; set; }
[XmlIgnore]
IList<ICategory> IComponent.Categories
{
    get { return Categories as IList<ICategory>; }
}

Это потому, что свойство интерфейса не предоставляет сеттер?

1 ответ

Решение

Нет. Проблема в том, что Contravariance не поддерживается List<T> а также IList<T>, Вот хорошая ссылка.


Посмотрите на этот простой код:

public interface IMyInterface
{

}

public class MyImplementation : IMyInterface
{

}

List<MyImplementation> myImplementations = new List<MyImplementation>();
Console.WriteLine(myImplementations as IList<IMyInterface> == null); // OUTPUT: true!!

Итак, как вы можете видеть, Categories as IList<ICategory> всегда будет нулевым. В то время как Categories as IList<Category> будет в порядке.

Ничего общего с сериализацией.

Другие вопросы по тегам