Ultimately, I suspect the problem is here:
[ProtoContract] [ProtoInclude(1, typeof(AntRule1))] [ProtoInclude(2, typeof(AntRule2))] [ProtoInclude(3, typeof(CatRule1))] [ProtoInclude(4, typeof(CatRule2))] public interface IRule<T> where T : IBeast
This suggests that for any T
, IRule<T>
has 4 children. This has a side effect, saying that if you have more than one T
, each of AndRule1
... CatRule2
each of them has "n" parents, which is not very good. Assume instead that IRule<Ant>
has 2 ant -rules, etc. (In the end, I doubt that CatRule1
indeed an implementation of IRule<Ant>
). Currently, this can only be expressed through RuntimeTypeModel
, since attributes will always be applied to all T
:
[ProtoContract] public interface IRule<T> where T : IBeast
and
// 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));
and then it works. Please note that configuration should only be done once, usually at application startup.
Thinking about this, I could probably just test at runtime, and in the case of generics, just ignore any that don't apply - by which I mean when evaluating IRule<Dog>
, consider only specific types if they implement IRule<Dog>
. I'm still in two minds.