I'm writing an immutable binary tree class where all of the methods (Insert, Remove, RotateLeft, etc) return a new instance of a tree instead of modifying it in place.
I'm going to be creating lots of different implementations of tree: Avl tree, red-black tree, splay tree, etc. I have the following:
public class AbstractBinaryTree<TreeType, T>
where TreeType : AbstractBinaryTree<TreeType, T>
where T : IComparable<T>
{
protected abstract TreeType CreateNode(TreeType left, T value, TreeType right);
protected abstract T Value { get; }
protected abstract TreeType Left { get; }
protected abstract TreeType Right { get; }
protected abstract bool IsNil();
public TreeType Insert(T item)
{
if (this.IsNil())
{
return CreateNode(this, item, this);
// ^ doesn't compile, can't convert type
// AbstractBinaryTree<TreeType, T> to type TreeType
}
else
{
int compare = item.CompareTo(this.Value);
if (compare < 0)
{
return CreateNode(this.Left.Insert(item), this.Value, this.Right);
}
else if (compare > 0)
{
return CreateNode(this.Left, this.Value, this.Right.Insert(Value));
}
else
{
return this;
// ^ doesn't compile, can't converrt type
// AbstractBinaryTree<TreeType, T> to type TreeType
}
}
}
}
The idea here is that AbstractBinaryTree is a tree node -- more than that, it is the same type as TreeType
. If I can get the above base class working correctly, then I can write something like this:
public class AvlTree<T> : AbstractBinaryTree<AvlTree<T>, T>
{
public override AvlTree<T> Insert(T item) { return Balance(base.Insert(item)); }
}
so that my Insert method returns AvlTree<T>
instead of AbstractBinaryTree<AvlTree<T>, T>
. However I can't even get this far because the base class doesn't compile.
How do I pass an instance of AbstractBinaryTree into a method which takes a type TreeType
?