ProtoBuf-сеть, сериализующая IEnumerable <T> - PullRequest
7 голосов
/ 17 октября 2011

Я пытаюсь использовать ProtoBuf-NET в своем проекте (в основном это проект Silverlight 4).

У меня трудности с сериализацией коллекций моделей, все они определены так:

private List<T> _itemsSet;
public IEnumerable<T> TSet
{
    get {return _itemsSet;}
    set {_itemsSet = value == null ? new List<T>() : new List<T>(value);}
}
public void AddT(T item)
{
    //Do my logic here
    _itemsSet.Add(item);
}

Обновление: Сначала я не могу его сериализовать - No serializer defined for type: System.Collections.Generic.IEnumerable 1 [MyType] `. Во-вторых, я думаю, что я не смогу десериализовать его на основе ручного анализа и анализа исходного кода protobuf-net.

  1. Есть ли способ расширить protobuf-Net для предоставления делегата внешнему методу Add в атрибуте ProtoMemeber?
  2. Почему использование ProtoMember(1, OverwriteList=true) не работает? Разве это не предполагает перезаписи коллекции и не должно заботиться о методе Add<T>()? Почему просто не пытайтесь установить это свойство в T [] или List<T>, или в любой набор, назначаемый на IEnumerable<T>?
  3. Есть ли способ предоставить пользовательский механизм отражения для работы с приватными полями в Silverlight, например: внедрение: public interface IReflectable{ object GetValue(FieldInfo field); void SetValue(FieldInfo field, object value); } для работы с приватными полями. Я использовал такой подход для работы с приватными полями с Db4o: http://community.versant.com/Forums/tabid/98/aft/10881/Default.aspx
  4. Какие у меня есть варианты, кроме создания унаследованных MyTypeCollection<T> : Collection<T>?

Ответы [ 2 ]

4 голосов
/ 17 октября 2011
  1. нет тока, нет;тип должен иметь (как минимум) метод Add.Хотя у меня нет возражений против исследования возможности Add вне самого объекта, это сложно, поскольку вы затем смотрите на другой «первичный» объект (последовательность против контейнера).Тем не мение;если ваш родительский объект реализован IEnumerable<T> (возвращает _itemsSet.GetEnumerator() и т. д.), то он найдет Add автоматически

  2. Я не вижу контекстаВот;тем не менее, я подозреваю, что без Add все еще не рад рассматривать его как список в первую очередь .Я вижу, как вы идете с этим, хотя, и, возможно, это способ, которым это могло бы объяснить "я могу использовать List<T> здесь)

  3. Это не то, что я"Если честно, мы провели расследование, поэтому: нет

  4. Тип, выставленный в свойстве, должен как минимум: внедрить IEnumerable (хотя IEnumerable<T> будет предпочтительным) и выставитьAdd(T) метод. Он не обязательно должен быть Collection<T> / List<T> / etc - просто: он должен (в настоящее время) иметь некоторый механизм для добавления. IList<T> будет прагматичнымвариант, но я понимаю, что это не совсем то, что вы хотите.

Джонатан прав, что суррогат для внешнего класса (вещь, которая может также иметь значение _itemsSet, TSet и AddT).

Если существует внешний класс only , чтобы иметь коллекцию и метод add,тогда просто добавив : IEnumerable<T> и переименовав AddT в Add, возможно, все заработает.

1 голос
/ 17 октября 2011

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

Я должен критиковать Марка за добавление атрибутов ProtoContract и ProtoMemeber, которые соблазняют пользователей повторно использовать ихмодель, приписывая это.

...