这似乎有效:
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>));
其中UserEvent定义为:
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();
}
答案 0 :(得分:2)
首先,关于您的反思示例,小心 - 键(数字)非常重要,您必须能够在将来可靠地重现此数字。我不希望你添加一个新的子类型,并且发现你的所有数据都失败了,因为偏移是一个偏移。
无法重现问题;以下工作正常 - 请让我知道我错过了什么:
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);
}
}