I don't know how to solve your problem other than by starting over with a much simpler system. This seems very over-engineered.
To explain why your code is wrong, look at this greatly simplified version of it:
public interface IInitializable<TParent> { }
public class SceneSystemJob<TItem>
where TItem : IInitializable<SceneSystemJob<TItem>>
{ }
public class GameObject : SceneSystemJob<Component> { } // Error here
public class Component : IInitializable<GameObject> { }
The error is that Component
cannot be used as TItem
. Why not? It seems plausible that this should work:
TItem
requires that it implementIInitializable<SceneSystemJob<TItem>>
.Component
implementsIInitializable<GameObject>
GameObject
is a special kind ofSceneSystemJob<Component>>
- Therefore
Component
meets the criterion of implementingIInitializable<SceneSystemJob<Component>>
The conclusion unfortunately does not follow from the premise unless IInitializable<T>
is covariant in T. Since your real implementation has a method which takes in a T, it cannot be covariant in T.
Think about it this way. An IInitializable<T>
is like a container that you can put a T
into. The constraint says "you need to give me a TItem
such that it is a container that I can put any SceneSystemJob<TItem>
into." You are giving it a container that you can only put GameObject
into. Therefore the constraint is not met.
It's like the constraint says "I need a cage that can contain any animal" and you're handing it an aquarium. Well, that's a cage that can contain any fish, but the constraint doesn't say "I need a cage for some animal, your choice", it says it needs a cage for any animal.
I don't know how you fix this mess you've gotten yourself into other than starting over and not being so excessively generic.