You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# protobuf-net泛型继承报PBN0012警告原因及免重写解决方案

警告性质说明

这个PBN0012警告是protobuf-net 3.x及以上版本的预期行为,不属于框架bug。
根本原因在于:你给开放泛型类型BaseState<T>(未填充泛型参数的泛型定义)添加了[ProtoInclude]声明子类,但实际运行时ExampleState继承的是构造后的封闭泛型类型BaseState<ExampleModel>,二者是完全不同的运行时类型,框架校验时无法匹配继承关系,因此触发警告。


低改造成本解决方案

无需重写现有模型结构,可直接选择以下任意一种方案修复:

方案1:启动时批量动态注册继承关系(推荐)

仅需要在应用初始化阶段添加一段反射注册逻辑,完全不需要修改现有模型的特性定义,适配大量现有模型的场景:

// 程序启动时执行一次
var baseOpenType = typeof(BaseState<>);
// 扫描所有继承自BaseState<>的子类
var subTypes = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a => a.GetTypes())
    .Where(t => !t.IsAbstract && t.BaseType != null 
        && t.BaseType.IsGenericType 
        && t.BaseType.GetGenericTypeDefinition() == baseOpenType);

foreach (var subType in subTypes)
{
    // 获取子类对应的封闭泛型基类
    var constructedBaseType = subType.BaseType;
    // 注册继承关系,字段编号和你之前[ProtoInclude]填的保持一致即可
    RuntimeTypeModel.Default.Add(constructedBaseType, true)
        .AddSubType(1, subType);
}

注册完成后删除原来BaseState<T>上的[ProtoInclude(1, typeof(ExampleState))]特性即可消除警告。

方案2:新增非泛型基类适配

如果不想加运行时代码,也可以新增一层非泛型基类承载继承声明,原有模型逻辑完全不变:

// 新增非泛型基类
[ProtoContract]
[ProtoInclude(1, typeof(ExampleState))]
public abstract class BaseState
{
    [ProtoMember(3)]
    public abstract string Id { get; }
}

// 原有泛型基类调整继承关系
[ProtoContract]
public abstract class BaseState<T> : BaseState
{
    [ProtoMember(2)]
    public T Model { get; set; }

    public override string Id => this.Model.Id;
}

// 原有子类完全不需要修改
[ProtoContract]
public class ExampleState: BaseState<ExampleModel>
{
    [ProtoMember(1)]
    public DateTimeOffset LastSeenAt { get; set; }
}

内容的提问来源于stack exchange,提问作者FranzHuber23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:45:07