How to restrict a generic type parameter to child classes?

302 Views Asked by At

I'm trying to do something like that:

    internal class ConcreteLinkedItem : GenericLinkedItem<ConcreteLinkedItem>
    { //Specific methods which use GenericLinkedItem
    }
    internal class GenericLinkedItem<TItem>
        where TItem : GenericLinkedItem<TItem>
    {
        public TItem? Next { get; private set; }
        public TItem? Previous { get; private set; }

        public void AttachNext(TItem item)
        {
            Next = item;
//Error CS0266 Cannot implicitly convert type 'GenericLinkedItem<TItem>' to 'TItem'...  
            item.Previous = this; 

        }
    }

The only solutions I have in mind are:

  • Explicit cast (no compile time type check)
            item.Previous = (TItem)this;

  • Abstract method to retrieve this (boilerplate)
        public void AttachPrevious(TItem item)
        {
            Previous = item;
            item.Next = GetThis();
        }

        protected abstract TItem GetThis();
  • Use composition instead of inheritance aka System.Collections.Generic.LinkedList (even more boilerplate).

Any beautiful ideas?

PS: For now I go with "protected abstract TItem This { get; }". Which still is not what I want as you can mix different item (node) types, but is at least type safe:

    internal class ConcreteLinkedItem : GenericLinkedItem<ConcreteLinkedItem>
    { //Specific methods which use GenericLinkedItem
        protected override ConcreteLinkedItem This => this;
    }
    internal abstract class GenericLinkedItem<TItem>
        where TItem : GenericLinkedItem<TItem>
    {
        public TItem? Next { get; private set; }
        public TItem? Previous { get; private set; }

        public void AttachPrevious(TItem item)
        {
            Previous = item;
            item.Next = This;
        }

        protected abstract TItem This { get; }
    }
0

There are 0 best solutions below