Используя 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 информации, но подделывая ее как подобъект. Это, как минимум, стоит попробовать; п

Другие вопросы по тегам