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:
item.Previous = (TItem)this;
public void AttachPrevious(TItem item)
{
Previous = item;
item.Next = GetThis();
}
protected abstract TItem GetThis();
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; }
}
use an interface:
internal class ConcreteLinkedItem : IGenericLinkedItem<ConcreteLinkedItem>
{
public ConcreteLinkedItem? Next { get; private set; }
public ConcreteLinkedItem? Previous { get; private set; }
public void AttachNext(ConcreteLinkedItem item)
{
Next = item;
item.Previous = this;
}
}
internal interface IGenericLinkedItem<TItem> where TItem : IGenericLinkedItem<TItem>
{
TItem? Next { get; }
TItem? Previous { get; }
void AttachNext(TItem item);
}
or if you must have a generic class then you'll need a cast:
internal class ConcreteLinkedItem : BaseLinkedItem<ConcreteLinkedItem>
{
//Specific methods which use GenericLinkedItem
}
internal class BaseLinkedItem<TItem> : IGenericLinkedItem<TItem> where TItem : BaseLinkedItem<TItem>
{
public TItem? Next { get; private set; }
public TItem? Previous { get; private set; }
public void AttachNext(TItem item)
{
Next = item;
item.Previous = (TItem)this;
}
}
internal interface IGenericLinkedItem<TItem> where TItem : IGenericLinkedItem<TItem>
{
TItem? Next { get; }
TItem? Previous { get; }
void AttachNext(TItem item);
}