Как и для всех атрибутов, информация о включенных типах атрибутов применяется ко всем закрытым типам из определения универсального типа.Таким образом, то, что вы на самом деле определили (для protobuf-net):
BaseClass
: GenericBaseClass<object>
: GenericDerivedClass<object>
: DerivedClass1
: DerivedClass2
: GenericDerivedClass<string>
: DerivedClass1
: DerivedClass2
: GenericBaseClass<string>
: GenericDerivedClass<object>
: DerivedClass1
: DerivedClass2
: GenericDerivedClass<string>
: DerivedClass1
: DerivedClass2
Как видите, существует множество дубликатов, что явно сбивает с толку.Так как аргументы атрибута не могут использовать параметры типа, это оставляет возможность добавить какой-то нечетный механизм предикатов, что очень запутанно в IMO.ИМО, было бы лучше смоделировать это вручную (удалив атрибуты ProtoInclude
).Я подозреваю Ваша предполагаемая модель:
BaseClass
: GenericBaseClass<object>
: GenericDerivedClass<object>
: DerivedClass2
: GenericBaseClass<string>
: GenericDerivedClass<string>
: DerivedClass1
protobuf-net может работать с этим, но для объяснения модель требует "v2" и RuntimeTypeModel
:
Обратите также внимание, что object
является проблемой для protobuf;protobuf-net может подделать его с помощью опции динамического типа, но это ... не идеально.Конечно, он не может сериализовать object
, поэтому для теста я подставил строку.Также обратите внимание, что BaseProperty1
, BaseProperty2
и AdditionalProperty
в настоящее время не помечены для сериализации, но могут быть тривиальными.
В любом случае:
RuntimeTypeModel.Default[typeof(BaseClass)]
.AddSubType(10, typeof(GenericBaseClass<object>))
.AddSubType(11, typeof(GenericBaseClass<string>));
RuntimeTypeModel.Default[typeof(GenericBaseClass<object>)]
.AddSubType(10, typeof(GenericDerivedClass<object>));
RuntimeTypeModel.Default[typeof(GenericBaseClass<object>)][5].DynamicType = true; // object!
RuntimeTypeModel.Default[typeof(GenericDerivedClass<object>)]
.AddSubType(10, typeof(DerivedClass2));
RuntimeTypeModel.Default[typeof(GenericBaseClass<string>)]
.AddSubType(10, typeof(GenericDerivedClass<string>));
RuntimeTypeModel.Default[typeof(GenericDerivedClass<string>)]
.AddSubType(10, typeof(DerivedClass1));
DerivedClass2 i = new DerivedClass2() { BaseProperty1 = 1, BaseProperty2 = 2, DerivedClass2Property = 3, ResponseProperty = "some string" };
using (var file = System.IO.File.Create("test.bin"))
{
ProtoBuf.Serializer.Serialize(file, i);
}
using (var file = System.IO.File.OpenRead("test.bin"))
{
var o = ProtoBuf.Serializer.Deserialize<DerivedClass2>(file);
}
Вы не иметь для использования RuntimeTypeModel.Default
- на самом деле, я рекомендую использовать (и кэшировать) отдельную модель типов;но Serializer.Serialize
указывает на модель по умолчанию.Если вы создаете пользовательскую модель (TypeModel.Create
), просто сохраните ее где-нибудь и используйте оттуда Serialize
и т. Д.