Используя protobuf-net, как правильно сериализовать производный тип, который реализует интерфейс?
Я понимаю, что здесь есть похожие вопросы, но ни один из них не задает их так же просто, как мне нужно, вероятно, из-за отсутствия у меня опыта работы с protobuf. Я транскодирую для кэширующего клиента enyim и не могу понять, как создать класс, который является и производным, и правильно реализовать десериализацию интерфейса.
Для образца, подобного этому
public class BaseClass
{
}
public interface ISomeRules
{
}
public class DerivedClass : BaseClass, ISomeRules
{
}
public class ThirdClass
{
ISomeRules ruleUser;
}
Я хочу сделать что-то вроде этого, потому что я обычно использую атрибуты везде
[ProtoContract
,ProtoInclude(101,typeof(DerivedClass))
]
public class BaseClass
{
}
[ProtoContract
,ProtoInclude(102,typeof(DerivedClass))
]
public interface ISomeRules
{
}
[ProtoContract]
public class DerivedClass : BaseClass, ISomeRules
{
}
[ProtoContract]
public class ThirdClass
{
[ProtoMember(1)]
ISomeRules ruleUser;
}
но он не может кешировать молча. Если, как некоторые предложили, я удаляю ProtoContract
атрибут из ISomeRules
десериализация не удалась.
Это выполнимо с помощью protobuf-net? Как правильно это сделать? Должен ли я использовать TypeModel (которую я не осваиваю, но какие простые тесты показывают, имеет ту же проблему) вместо этого? Или сочетание TypeModel и атрибутов?
1 ответ
Поддержка интерфейса в protobuf-net предназначена для ограниченных сценариев, когда вы работаете над моделью на основе интерфейса, в частности для вложенных членов. Например:
[ProtoContract]
public class Foo {
[ProtoMember(1)]
public IBar Bar {get;set;}
}
Выше мы хотим иметь возможность сериализовать Bar
, но мы не могли бы знать много об этом. На самом деле, если Foo
гарантирует возврат ненулевого значения из Bar
protobuf-net даже не нужно ничего знать о конкретных типах и т. д. Он может просто заполнить объект, который ему дан.
В вашем примере, корневой объект, безусловно, BaseClass
, Я бы предположил, что ISomeRules
является вспомогательным и не нуждается в упоминании в модели. Однако, если вы хотите заполнить участников, которые открыты только через ISomeRules
, тогда вы можете попробовать (не проверено):
[ProtoMember(n)]
private ISomeRules Rules { get { return this; } }
Это тогда подвергает ISomeRules
информации, но подделывая ее как подобъект. Это, как минимум, стоит попробовать; п