Reputation: 2457
I'm trying to design a parent/children definition in C#, but receive some compilation errors, which are not clear for me:
namespace TestProject1
{
public abstract class BaseElement
{
}
public abstract class Child<T> : BaseElement
{
public BaseElement Parent { get; set; }
}
public abstract class Parent<T> : BaseElement
{
public IQueryable<BaseElement> Children { get; set; }
}
public abstract class ParentChild<TParent, TChild> : BaseElement
where TParent : Parent<BaseElement>
where TChild : Child<BaseElement>
{
public void AddChild(TChild child)
{
child.Parent = this;
}
}
public class Root : Parent<Trunk>
{
}
public class Trunk : ParentChild<Root, Branch>
{
}
public class Branch : ParentChild<Trunk, Leaf>
{
}
public class Leaf : Child<Branch>
{
}
}
One of the compilation errors is in line public class Trunk:
Error CS0311 The type
TestProject1.Root
cannot be used as type parameterTParent
in the generic type or methodParentChild<TParent, TChild>
. There is no implicit reference conversion fromTestProject1.Root
toTestProject1.Parent<TestProject1.BaseElement>
.
But in fact there is a path from Root
to Parent<BaseElement>
as Root
inherits from Parent<Trunk>
and Trunk
is a BaseElement
due to the fact that BaseElements
inherits from ParentChild
, which is a direct successor from BaseElement.
The other compilation errors are similar, but for the Branch
type in Trunk
and the Trunk
and Leaf
parameters of Branch
.
Upvotes: 0
Views: 426
Reputation: 6060
It's not the inheritance from BaseElement
at play here. You would have this same problem if none of these classes derived from BaseElement
. The type definition of Root
depends on Trunk
. The type definition of Trunk
depends on Root
. You can't have a circular dependency like that with generics in C#. Effectively you are trying to define Root as Root<Parent<ParentChild<Root, Branch>>>
so Root derives from Root, which is a problem.
Upvotes: 1