これはうまくいくようです:
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
次の(上記のコードの3番目の段落を置き換えようとする)は機能しないようです。コンパイルエラーや実行時エラーは発生しませんが、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();
}