使用protobuf-net,序列化实现接口的派生类型的正确方法是什么?

本文关键字:方法 是什么 类型 派生 序列化 实现 接口 使用 protobuf-net | 更新日期: 2023-09-27 17:53:55

我意识到这里也有类似的问题,但没有一个问题像我需要的那样直截了当,可能是因为我缺乏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;
}

但是缓存失败。如果像一些人建议的那样,我从ISomeRules中删除ProtoContract属性,反序列化将失败。

使用protobuf-net是否可行?正确的做法是什么?我应该使用TypeModel(我没有掌握,但简单的测试表明有相同的问题)吗?还是TypeModel和属性的组合?

使用protobuf-net,序列化实现接口的派生类型的正确方法是什么?

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信息,但将其欺骗为子对象。这至少值得一试;p