Нужна помощь с самым тривиальным примером protobuf-net 4

  [DataContract]
  public class I<TId>
  {
    [DataMember(Order = 1)]
    public TId Id { get; set; }
  }

  [DataContract]
  public class J : I<int>
  {
    [DataMember(Order = 1)]
    public string Description { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var o = new J { Id = 5, Description = "xa-xa", };
      using (var ms = new MemoryStream())
      {
        Serializer.Serialize(ms, o);
        ms.Position = 0;
        var o2 = Serializer.Deserialize<J>(ms);
        Debug.Assert(o.Id == o2.Id);
      }
    }
  }

Почему утверждение не выполняется и как это исправить?

Спасибо.


person mark    schedule 08.06.2011    source источник


Ответы (1)


Это терпит неудачу, потому что protobuf-net не может обрабатывать наследование, если вы не дадите ему больше подсказки либо через атрибуты, либо через модель типа времени выполнения - по сути, ему нужно откуда-то получить номер поля (то есть от вас). Я согласен с тем, что предупреждение о трассировке может оказаться полезным в этом случае, поскольку разумно ясно, что в этом сценарии наследования, вероятно, есть нечто большее, чем просто J.

Следующее дополнение (во время выполнения) исправляет это:

RuntimeTypeModel.Default.Add(typeof(I<int>), true).AddSubType(2, typeof(J));

(единственное значение 2 в том, что оно не конфликтует ни с какими другими полями, определенными для I<int>).

person Marc Gravell    schedule 08.06.2011
comment
Зачем нужна эта неоднозначность? Я понимаю необходимость в этом, когда статический тип сериализуемого объекта является одним из базовых типов, и в этом случае десериализатор должен знать, какой производный тип создавать экземпляр. Но здесь десериализованный тип однозначен, не так ли? - person mark; 09.06.2011
comment
@mark акцент делается не на знании, а на крайне важном номере поля. Номера полей управляют насестом в protobuf (спецификация Google). Я использую их здесь как часть фактического разрешения типа - это I<int>, J, какой-то подкласс J или какой-то не-4_ подкласс I<int> - person Marc Gravell; 09.06.2011