Может ли protobuf-net сериализировать эту комбинацию интерфейса и общего набора? - PullRequest
3 голосов
/ 20 апреля 2010

Я пытаюсь сериализовать ItemTransaction, и у protobuf-net (r282) возникла проблема.

ItemTransaction : IEnumerable<KeyValuePair<Type, IItemCollection>></code>

и ItemCollection выглядит следующим образом:

FooCollection : ItemCollection<Foo>
ItemCollection<T> : BindingList<T>, IItemCollection
IItemCollection : IList<Item>

где T является производным типом Item. ItemCollection также имеет свойство типа IItemCollection.

Я сериализирую так:

IItemCollection itemCol = someService.Blah(...);
...
SerializeWithLengthPrefix<IItemCollection>(stream, itemCol, PrefixStyle.Base128);

Моя конечная цель - сериализовать ItemTransaction, но я зацеплен за IItemCollection.

Элемент и его производные типы могут быть [de] сериализованы без проблем, см. [1], но десериализация IItemCollection не выполняется (сериализация работает). ItemCollection имеет свойство ItemExpression и при десериализации protobuf не может создать абстрактный класс. Это имеет смысл для меня, но я не уверен, как пройти через это.

ItemExpression<T> : ItemExpression, IItemExpression
ItemExpression : Expression

ItemExpression является абстрактным, как и выражение

Как мне заставить это работать должным образом?

Кроме того, я обеспокоен тем, что ItemTransaction потерпит неудачу, так как коллекции IItemCollection будут отличаться и неизвестны во время компиляции (ItemTransaction будет иметь FooCollection, BarCollection, FlimCollection, FlamCollection и т. Д.).

Чего мне не хватает (Марк)?

[1] protobuf-net [de] сериализация через границы сборки

1 Ответ

1 голос
/ 21 апреля 2010

Мне не совсем понятен весь сценарий; однако Merge может использоваться для передачи конкретного элемента (в случае, если вы хотите создать пустой конкретный экземпляр самостоятельно и позволить protobuf-net заполнить свойства).

Если ItemExpression украшен [ProtoInclude(...)] для ожидаемого ItemExpression<T>, то должно разрешить десериализацию - абстрактные типы поддерживаются так же долго, как и когда они не обнаруживают, что их нужно создавать! Смотрите также мой ответ здесь , который показывает это в использовании.

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


Основываясь на некоторых сторонних примерах, я пришел к выводу, что поддерживается , но:

  • , если вы просто используете Deserialize..., по умолчанию будет создан самый производный IList<T> как List<T>; вы можете обойти это, используя Merge вместо этого, передавая конкретный экземпляр списка по вашему выбору для заполнения
  • все из Item, Foo, Bar должны быть помечены как типы контрактов с соответствующими маркерами наследования между Item и Foo и Item и Bar
  • в "v2" (скоро) больше возможностей для управления конкретными типами списков (и типами элементов для нетипизированных списков)
  • похоже, есть сбой, связанный с десериализацией списка, когда указанный тип элемента не является корневым типом. Похоже, что это было исправлено автоматически в "v2", но мне нужно прогнать его (к сожалению, это касается внешних методов оболочки WithLengthPrefix / list, над которыми я все еще работаю)
  • в "v2" вы можете делать все это, не нуждаясь в атрибутах, если хотите (хотя в какой-то момент это еще нужно сказать, как)

Но да; он должен работать. Я отправил вам образец по электронной почте и намереваюсь привести в порядок вышеупомянутые внешние методы.

...