Protobuf-net RuntimeTypeModel не сериализует члены базового класса

Скажем, у меня есть следующий базовый класс:

[DataContract]
[Serializable]
public abstract class DimensionEntity
{
    [DataMember(Order = 1)]
    private readonly Date effectiveDatespan;
    ...
}

И следующий производный класс:

[DataContract]
[Serializable]
public class ClearingSite : DimensionEntity
{
    [DataMember(Order = 1)]
    private readonly string code;
    ...
}

Когда я сериализую экземпляр ClearingSite следующим образом:

        model.Add(typeof(ClearingSite), true);
        model.Serialize(ms, clearingSite);

Я вижу, что только code элемент ClearingSite сериализуется; значение элемента effectiveDatespan базового класса не сериализуется.

Два примечания:

  1. Я вижу, что член BaseType добавленного ProtoBuf.Meta.MetaType имеет значение null, из-за чего член effectiveDatespan не сериализуется; вместо этого, если я скомпилирую модель, ее элемент BaseType будет правильно установлен в DimensionEntity (хотя позже произойдет сбой, поскольку элементы равны private readonly и, следовательно, недоступны для скомпилированной модели);
  2. Конечно, я могу объявить ClearingSite известным типом DimensionEntity, но я не понимаю, зачем это нужно: я не сериализую DimensionEntity, я сериализую (и десериализую) ClearingSite, и, кроме того, DataContractSerializer делает не требует, чтобы я добавлял KnownType к DimensionEntity, если я сериализую ClearingSite.

Из других ответов Марка похоже, что Protobuf потребует атрибут KnownType (или ProtoInclude), чтобы получить «важный номер поля» (цитата), но это, похоже, не так, поскольку CompiledModel работает полностью хорошо без ProtoInclude.

Обратите внимание, что я стараюсь использовать только атрибуты System.Runtime.Serialization, так как я пытаюсь, чтобы моя объектная модель не знала о сериализаторах в будущем.


person Gabriele Giuseppini    schedule 01.05.2012    source источник


Ответы (1)


Обязательно требуется ProtoInclude или аналогичный. Если что-то странным образом происходит с скомпилированной версией, то это ошибка, которую я могу исследовать.

Если вы не хотите добавлять в свой тип атрибуты, отличные от BCL, это можно сделать во время выполнения:

RuntimeTypeModel.Default[typeof(BaseType)]
    .AddSubClass(.....);

(или что-то в этом роде - я не за ПК)

person Marc Gravell    schedule 01.05.2012
comment
Спасибо, Марк. Какие недостатки вы бы заметили, если бы кто-то реализовал вспомогательную функцию, которая при добавлении типа T в модель посещала бы иерархический путь от T до object и для каждого типа Ti, отмеченного как DataContract, автоматически Add(typeof(Ti)).AddSubClass(T)? - person Gabriele Giuseppini; 02.05.2012
comment
@Gabriele, единственная проблема, с которой я столкнулся, заключается в том, что число важно, и вам нужно иметь возможность надежно получать то же самое число в будущем, даже когда дополнительные типы были добавлены в систему, и вещи были переименованы. Если вы можете это сделать: хорошо. - person Marc Gravell; 02.05.2012