В конечном счете, я подозреваю, что проблема здесь:
[ProtoContract]
[ProtoInclude(1, typeof(AntRule1))]
[ProtoInclude(2, typeof(AntRule2))]
[ProtoInclude(3, typeof(CatRule1))]
[ProtoInclude(4, typeof(CatRule2))]
public interface IRule<T> where T : IBeast
Это говорит о том, что для любого T
, IRule<T>
имеет 4 детей. Это побочный эффект: , если , у вас более одного T
, у каждого из AndRule1
... CatRule2
у каждого "n" родителей, что нехорошо. Давайте вместо этого предположим, что IRule<Ant>
имеет 2 правила муравья и так далее ... (в конце концов, я сомневаюсь, что CatRule1
действительно является реализацией IRule<Ant>
). В настоящее время это может быть выражено только через RuntimeTypeModel
, поскольку атрибуты всегда применяются для all T
:
[ProtoContract]
public interface IRule<T> where T : IBeast
и
// note these are unrelated networks, so we can use the same field-numbers
RuntimeTypeModel.Default[typeof(IRule<Ant>)]
.AddSubType(1, typeof(AntRule1)).AddSubType(2, typeof(AntRule2));
RuntimeTypeModel.Default[typeof(IRule<Cat>)]
.AddSubType(1, typeof(CatRule1)).AddSubType(2, typeof(CatRule2));
и тогда это работает. Обратите внимание, что настройку необходимо выполнить только один раз, обычно при запуске приложения.
Подумав об этом, я мог бы , вероятно, просто протестировать во время выполнения, а в случае обобщений просто игнорировать все, что не применимо - под этим я подразумеваю при оценке IRule<Dog>
, учитывать только типы, если они реализуют IRule<Dog>
. Я все еще в раздумье.