Manuel Faux
Manuel Faux

Reputation: 2457

C# Generic Parent Children Definition

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 parameter TParent in the generic type or method ParentChild<TParent, TChild>. There is no implicit reference conversion from TestProject1.Root to TestProject1.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

Answers (1)

Tim
Tim

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

Related Questions