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; }
}