Search code examples
c#oopinheritancepolymorphism

System.InvalidCastException while inheriting a class


I've created a class for a binary search tree called BSTree. I want to create a class for AVL tree called AVLTree and inherit BSTree class. But when I override a virtual method from BSTree class in AVLTree class and want to perform type casting from BSTree to AVLTree using round brackets notation, for example, AVLTree node = (AVLTree)base.SomeMethod(...), the error System.InvalidCastException: "Unable to cast object of type 'BSTree.BSTree' to type 'BSTree.AVLTree'." occurs.

My BSTree class looks like this (I remained only necessary part of it):

class BSTree
{
    public int Value { get; private set; }
    public BSTree Left { get; set; }
    public BSTree Right { get; set; }
    public BSTree Parent { get; set; }
    public BSTree(int value) { Value = value; }
    protected virtual BSTree InsertBase(int value)
    {
        BSTree node = this, parent = null;
        while (node != null)
        {
            if (value == node.Value) return null;
            parent = node;
            node = value > node.Value ? node.Right : node.Left;
        }
        node = new BSTree(value);
        node.Parent = parent;
        if (value > parent.Value) parent.Right = node;
        else parent.Left = node;
        return node;
    }
    public virtual void Insert(int value) { InsertBase(value); }
}

My AVLTree class (with a function for inserting only) looks like this:

class AVLTree : BSTree
{
    public int BalanceFactor { get; set; }
    public AVLTree(int value) : base(value) { }
    protected override BSTree InsertBase(int value)
    {
        AVLTree node = (AVLTree)base.InsertBase(value); // error happens there
        // following operations that calculate balance factors for all ancestors
        return node;
    }
}

I want AVLTree nodes to be inserted in exact the same manner as BSTree nodes, but AVLTree nodes need to have also a BalanceFactor property, apart from Left, Right and Parent, that come from BSTree class


Solution

  • Here the base class creates the node object that it later returns:

    node = new BSTree(value);
    

    This object is always of the type BSTree, so can never be downcast to an inherited type.

    If you want to make this variable, you could consider making use of the Factory Method pattern. Something like this:

    node = CreateNode(value);
    

    where CreateNode is a virtual method that a deriving class can override.