Let's say I have a set of classes/interfaces:
class ObjectData { }
class UnitData : ObjectData { }
class Component1Data : UnitData { }
class Component2Data : UnitData { }
interface IObject { }
interface IUnit : IObject { }
interface IComponent1 : IUnit { }
interface IComponent2 : IUnit { }
abstract class Object<D, O, I>
where D : ObjectData
where O : Object<D, O, I>, I, new()
where I : IObject
{ }
The point of primary interest here is an Object
class which is a base generic class in some hierarchy. Type-param "O" is a way to specify type of an actual class which is derived from the Object
. Thus, something like this can be declared and compiled w/o problems:
class Unit : Object<UnitData, Unit, IUnit>, IUnit { }
But what i want to do, is to define another generic "2nd-level" class derived from Object that should also behave as a base class for a couple of similar "3rd-level" entities. And it have to be non-abstract because it is also some sort of an entity. So i need to define something like this:
class Unit<D, I> : Object<D, Unit<D, I>, I>, IUnit
where D : UnitData
where I : IUnit
{ }
class Component1 : Unit<Component1Data, IComponent1>, IComponent1 { }
class Component2 : Unit<Component2Data, IComponent2>, IComponent2 { }
And it produces following compilation error:
error CS0311: The type 'Unit<D, I>' cannot be used as type parameter 'O' in the generic type or method 'Object<D, O, I>'. There is no implicit reference conversion from 'Unit<D, I>' to 'I'.
The question is why? In my vision if Unit<D, I>
is implementing IUnit
, and param "I" is specified as where I : IUnit
, then all should be fine. That's how i see it. What i don't see?