Protobuf-net v2 模型中的泛型

本文关键字:泛型 模型 v2 Protobuf-net | 更新日期: 2023-09-27 18:32:30

这似乎有效:

Model.Add(typeof(ScsMessage), true).AddSubType(20, typeof(Request));
Model.Add(typeof(ScsMessage), true).AddSubType(200, typeof(Event));
Model.Add(typeof(Request), true).AddSubType(102, typeof(Message));
Model.Add(typeof(Request), true).AddSubType(103, typeof(Like));
Model.Add(typeof(Request), true).AddSubType(104, typeof(Tag));
Model.Add(typeof(Event), true).AddSubType(202, typeof(UserEvent<Message>));
Model.Add(typeof(Event), true).AddSubType(203, typeof(UserEvent<Like>));
Model.Add(typeof(Event), true).AddSubType(204, typeof(UserEvent<Tag>));

其中用户事件定义为:

public class UserEvent<T> :Event where T:Request

以下内容(尝试替换上面的第三段代码)似乎不起作用。它不会生成任何编译或运行时错误,但 UserEvent 的反序列化给出了时髦的结果。

Model.Add(typeof(Event), true).AddSubType(201, typeof(UserEvent<Request>));

有什么办法可以做到这一点吗?每次我定义一个新类时,它都会节省样板代码。

谢谢

编辑:使用以下反射来设置内容。放在这里以防有人发现它有用。

        foreach (Type type in FindAllDerivedTypes<ScsMessage>
                      (Assembly.GetAssembly(typeof(Request))))
        {
            Model.Add(typeof(ScsMessage), true).AddSubType(counter++, type);
        }
        foreach (Type type in FindAllDerivedTypes<Request>
                       (Assembly.GetAssembly(typeof(Request))))
        {
            Model.Add(typeof(Request), true).AddSubType(counter++, type);
            Type constructed = typeof(UserEvent<>).MakeGenericType(type);
            Model.Add(typeof(Event), true).AddSubType(counter++, constructed);
        }

.

       public static List<Type> FindAllDerivedTypes<T>(Assembly assembly)
       {
        var derivedType = typeof(T);
        return assembly
            .GetTypes()
            .Where(t =>
                t != derivedType && t.BaseType == derivedType  &&
                derivedType.IsAssignableFrom(t)
                ).ToList();
        } 

Protobuf-net v2 模型中的泛型

首先,关于您的反射示例,请注意 - 键(数字)非常重要,您必须能够在将来可靠地再现此数字。我不希望您添加新的子类型并发现所有数据都失败,因为偏移量相差一。

无法重现问题;以下工作正常 - 请让我知道我缺少什么:

using ProtoBuf.Meta;
using System;
class UserEvent<T> :Event where T:Request
{
    public override string ToString()
    { // to show what we are working with
        return "UserEvent-of-" + typeof (T).Name;
    }
}
// infer the : Request here from the ^^^^
class Message : Request{}
class Like : Request { }
class Tag : Request { }
class ScsMessage {}
// infer : ScsMessage here from the 2 AddSubType
class Request : ScsMessage {}
class Event : ScsMessage { }
class Program
{
    static void Main()
    {
        var Model = TypeModel.Create();
        Model.Add(typeof(ScsMessage), true).AddSubType(20, typeof(Request));
        Model.Add(typeof(ScsMessage), true).AddSubType(200, typeof(Event));
        Model.Add(typeof(Request), true).AddSubType(102, typeof(Message));
        Model.Add(typeof(Request), true).AddSubType(103, typeof(Like));
        Model.Add(typeof(Request), true).AddSubType(104, typeof(Tag));
        Model.Add(typeof(Event), true).AddSubType(202, typeof(UserEvent<Message>));
        Model.Add(typeof(Event), true).AddSubType(203, typeof(UserEvent<Like>));
        Model.Add(typeof(Event), true).AddSubType(204, typeof(UserEvent<Tag>));
        var obj = new UserEvent<Like>();
        var clone = Model.DeepClone(obj);
        Console.WriteLine(obj);
        Console.WriteLine(clone);
    }
}