C # XML сериализация объектов с IEnumerable - PullRequest
4 голосов
/ 02 марта 2012

всякий раз, когда я пытаюсь сериализовать объект, имеющий коллекцию IEnumerable, я получаю большую грязную ошибку, говорящую мне, что он не может сериализовать его, потому что это интерфейс. Теперь я понимаю, почему это происходит, но это поднимает некоторые другие вопросы для меня. Например, если я намереваюсь иметь коллекции в своих объектах И хочу сериализовать их, мне нужно прибегнуть к

  1. Использование List <>, CollectionBase, ReadOnlyCollectionBase в моих объектах.
  2. Создание моих объектов для реализации интерфейса IXmlSerializable.
  3. Украшая мои классы ужасными атрибутами.
  4. Написание собственного сериализатора.

Как лучше всего тренироваться?

Ответы [ 2 ]

6 голосов
/ 02 марта 2012

Говоря как автор сериализатора, я точно знаю, почему очень трудно надежно работать только с IEnumerable<T>, особенно для свойств "только для получения".Вы можете попробовать IList<T> (хотя меня это не удивит, если ему нужен конкретный тип, такой как List<T> / T[]), но я подозреваю, что реальная проблема заключается в том, что вы пытаетесь использоватьодна модель, которая делает две вещи, и недовольна необходимостью идти на компромисс, чтобы сделать это.

Хорошо: если вы не хотите ставить под угрозу свою модель предметной области, напишите отдельную модель DTO, котораяиспользуется для сериализации, и просто отображается между ними.Это обычно тривиально и позволяет сериализатору и модели предметной области превосходно справляться со своей работой.Это также очень поможет, когда вам нужно «версия» системы или ввести другой сериализатор (JSON, protobuf и т. Д.).

Re ваши пули:

  • Я подозреваю, что любой конкретныйТип списка (даже ваш собственный) с Add и т. д. будет работать
  • Я никому не рекомендую - больно надежно делать
  • ничего страшного в атрибутах;Опять же, я подозреваю, что ваша жалоба касается присвоения модели domain - так что: хорошо, не делайте этого - используйте отдельную модель;вы можете на самом деле делать все это во время выполнения, но это гораздо больше работы (см. XmlAttributeOverrides, но следите за утечками сборок, если вы это сделаете)
  • не стоит недооценивать, насколькоработа, которая есть;основы - соблазнительно легко;но нетривиальные сценарии могут быть жестокими
0 голосов
/ 02 марта 2012

Для использования классов интерфейса или производных классов вы ДОЛЖНЫ использовать конструктор XmlSerializer (Type type, Type [] extraTypes).

В extraTypes вы ДОЛЖНЫ включать все возможные классы, которые могут реализовывать интерфейсы в ваших классах.

...