C# (De)序列化特定子类而不使用[ProtoInclude]

C# (De)序列化特定子类而不使用[ProtoInclude],c#,protobuf-net,C#,Protobuf Net,我正在考虑将当前基于WCF的应用程序迁移到protobuf-net.Grpc。这似乎是可行的,但是如果不包含所有具有[ProtoInclude]属性的派生类,我就无法使protobuf net序列化(DTO类)基类的属性 简化的类层次结构: [DataContract] public abstract class DtoBase { [DataMember(Order = 1)] public int Id { get;set; } [DataMember(Order

我正在考虑将当前基于WCF的应用程序迁移到protobuf-net.Grpc。这似乎是可行的,但是如果不包含所有具有[ProtoInclude]属性的派生类,我就无法使protobuf net序列化(DTO类)基类的属性

简化的类层次结构:

[DataContract]
public abstract class DtoBase 
{
    [DataMember(Order = 1)]
    public int Id { get;set; }
    [DataMember(Order = 2)]
    public int Version { get;set; }
    [DataMember(Order = 3)]
    public EditState EditState { get;set; }
}

[DataContract]
public class PersonDto : DtoBase
{ 
    [DataMember(Order=4)]
    public string FirstName { get;set; }
    [DataMember(Order=5)]
    public string LastName { get;set; }
}

我已经调查了相关的问题,所有这些问题都归结为这样一个事实:在反序列化过程中应该知道特定的类型,或者应该有一种方法来确定它。我们的服务方法已经知道要使用的特定子类,例如,我们有如下方法

[ServiceContract]
public interface IPersonService 
{
    [OperationContract]
    ScalarResult<PersonDto> GetById(personId);
}
[服务合同]
公共接口IPersonService
{
[经营合同]
ScalarResult GetById(personId);
}
DataContractSerializer可以做到这一点——当特定子类已知时,反序列化基类属性。当您反序列化具有基类签名的子类时,它需要提示(已知类型),比如返回PersonDto而不是DtoBase。但当特定的子类已知时,就不需要已知的类型,一切都正常工作


所以问题是如何对protobuf网络进行同样的操作?如果这是不可能的,为什么呢?

Protobuf net和任何库一样,会做出某些假设和妥协。如果它想支持其他场景,就需要对它们进行指定、设计、实现、测试和支持——所有这些都需要时间。到目前为止,您描述的场景:还没有投入时间

可以使用
RuntimeTypeModel
API配置基本类型属性,但我必须强调:每当出现问题时,基本上是:

我现有的模型与我选择的序列化程序不兼容

我的默认回答(基于在该领域数十年的经验)是:

如果您现有的模型不适合不同的序列化程序:停止与序列化程序对抗。相反,创建一个与新选择的序列化程序完美配合的新模型,并在(反)序列化时在模型之间填充垫片


我所说的场景非常简单:这里有一个类a的对象,它不需要序列化/反序列化。据我所知,没有其他序列化程序不能这样做,因为(已知)类型A的某些属性是继承的。因此,做出假设和妥协的原因尚不清楚。顺便说一句,它起作用了。它只需要代码中每个子类或等效配置的[ProtoInclude]属性。这可能不是一个交易破坏者。我是否正确理解,假设它需要支持所有可能的继承场景,以及替换原则等?我的意思是:因为它知道继承是一件事情,所以它目前有一个与继承一起工作的实现,它基于LSP的原因首先执行根继承。因此,它不会在基类型中查找属性,因为它假定继承将处理这些属性。现在,有3个选项可用:通过RuntimTypeModel手动配置类型;正式地告诉它继承关系;或者现在就接受这一点:这不是一个受支持的场景(它可能会成为一个场景,但需要工作),我明白了,谢谢!顺便说一句,您的响应会导致识别另一个选项—使基类属性抽象并在派生类中实现它们。我喜欢基类上的100多个+[ProtoInclude]属性,编译器会注意它们不会被忽略。所以protobuf-net将不会处理继承的属性。