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();
}
首先,关于您的反射示例,请注意 - 键(数字)非常重要,您必须能够在将来可靠地再现此数字。我不希望您添加新的子类型并发现所有数据都失败,因为偏移量相差一。
无法重现问题;以下工作正常 - 请让我知道我缺少什么:
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);
}
}