继承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
相关产品推荐
相关产品推荐

