Почему следующее использование protobuf-net является незаконным?

  public interface IYObject
  {
    string X { get; }
  }

  public class YObject : IYObject
  {
    public string X { get; set; }
  }

  public class D
  {
    public IYObject Y { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var m = RuntimeTypeModel.Default;
      m.Add(typeof(D), true).Add("Y");
      m.Add(typeof(IYObject), false).AddSubType(1, typeof(YObject)).Add("X");
      var d = new D { Y = new YObject { X = "a" } };
      using (var ms = new MemoryStream())
      {
        Serializer.Serialize(ms, d);
        ms.Position = 0;
        var d2 = Serializer.Deserialize<D>(ms);
        Debug.Assert(d.Y.X == d2.Y.X);
      }
    }
  }

Код дает сбой, когда я пытаюсь добавить подтип к IYObject:

System.InvalidOperationException occurred
  Message=Sub-types can only be adedd to non-sealed classes
  Source=protobuf-net
  StackTrace:
       at ProtoBuf.Meta.MetaType.AddSubType(Int32 fieldNumber, Type derivedType)
  InnerException: 

person mark    schedule 24.05.2011    source источник
comment
Подтипы могут быть добавлены только к незапечатанным классам — это не класс, так что это определенно не незапечатанный класс. Я постараюсь снять это ограничение в соответствии с вашими (и существующими) запросами. Но сначала... поспи.   -  person Marc Gravell    schedule 25.05.2011
comment
Вы действительно меня тренируете ;p Я аплодирую - вы вынуждаете меня добавлять много полировки в области, которые люди просили, начиная с v1. Вся суть новой модели типов v2 заключалась в том, чтобы сделать возможным такую ​​гибкость (из ваших сообщений), и до сих пор я очень доволен тем, что в новой модели заложена необходимая универсальность (т. е. ничто не мешало показу).   -  person Marc Gravell    schedule 25.05.2011


Ответы (1)


Примерно 2 минуты назад это было незаконно, потому что известные типы не поддерживались для интерфейсов.

Теперь такое использование является незаконным, поскольку оно не может безопасно сериализовать IYObject.X, так как у него нет установщика. Однако пока мы ограничиваемся членами интерфейсов, которые можно разумно сериализовать, или членами конкретного типа, теперь это зафиксировано. Используя либо атрибуты, либо модель типов. Доступные сценарии см. здесь. (через код или следующую общедоступную папку).

person Marc Gravell    schedule 24.05.2011
comment
В чем смысл логического аргумента в методе RuntimeTypeModel.Add? - person mark; 25.05.2011
comment
@Mark <param name="applyDefaultBehaviour">Whether to apply the inbuilt patterns, or jut add the type with no additional configuration.</param> - или короче (и я уточню документацию) - если оно ложно, никакие атрибуты не обрабатываются - вы должны настроить тип полностью вручную - person Marc Gravell; 25.05.2011