You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承BSTree类时触发System.InvalidCastException异常的技术问询

问题原因

你遇到的System.InvalidCastException是因为父类BSTree的InsertBase方法中,直接通过new BSTree(value)创建了父类实例,而不是AVLTree实例。C#中仅支持子类实例向上转换为父类,不能将父类实例向下强制转换为子类,所以这行转换代码必然报错。

解决方案

核心思路是让父类复用插入逻辑,但把创建节点的行为交给子类控制——在父类中定义一个创建节点的虚方法,子类重写该方法来创建自身类型的节点。这样父类InsertBase执行时,会调用子类的创建方法,返回的就是AVLTree实例,无需强制转换。

修改后的BSTree类

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 CreateNode(int value)
    {
        return new BSTree(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;
        }
        // 替换原有的new BSTree,调用CreateNode方法
        node = CreateNode(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); }
}

修改后的AVLTree类

class AVLTree : BSTree
{
    public int BalanceFactor { get; set; }
    public AVLTree(int value) : base(value) { }

    // 重写CreateNode方法,返回AVLTree实例
    protected override BSTree CreateNode(int value)
    {
        return new AVLTree(value);
    }

    protected override BSTree InsertBase(int value)
    {
        // 现在base.InsertBase返回的就是AVLTree实例,用as转换更安全
        AVLTree node = base.InsertBase(value) as AVLTree;
        if (node == null) return null;

        // 后续计算所有祖先平衡因子的操作示例
        AVLTree current = node.Parent as AVLTree;
        while (current != null)
        {
            // 计算平衡因子逻辑(示例)
            int leftHeight = GetHeight(current.Left as AVLTree);
            int rightHeight = GetHeight(current.Right as AVLTree);
            current.BalanceFactor = leftHeight - rightHeight;

            current = current.Parent as AVLTree;
        }

        return node;
    }

    // 辅助方法:计算AVL树节点高度(示例)
    private int GetHeight(AVLTree node)
    {
        if (node == null) return 0;
        return 1 + Math.Max(GetHeight(node.Left as AVLTree), GetHeight(node.Right as AVLTree));
    }
}

关键说明

  • 父类新增的CreateNode方法是虚方法,默认创建BSTree实例;子类AVLTree重写后创建AVLTree实例,这样父类插入逻辑无需修改,就能适配子类的节点类型。
  • 转换时推荐使用as关键字,避免强制转换直接抛出异常,可通过判断null来处理异常情况。
  • 后续处理平衡因子时,需要将Parent、Left、Right转换为AVLTree类型,才能访问BalanceFactor属性。

内容的提问来源于stack exchange,提问作者olesatthewheel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 16:22:55