初学阶段应通过多态与泛型集合联动“异常类型、处理逻辑、数据容器”,将异常视为可分类、收纳、调度的对象;用List<BaseException>统一收纳子类异常,靠virtual Handle()实现差异化处理,借泛型方法封装全流程,并以Dictionary<Type, Action<BaseException>>实现类型路由。

初学阶段用多态+泛型集合理清异常脉络,关键不是堆砌语法,而是把“异常类型”“处理逻辑”和“数据容器”三者联动起来看——让异常变成可分类、可收纳、可统一调度的对象。
用泛型集合收纳同类异常对象
别再把异常当零散的错误提示。定义一个泛型集合如 List<BaseException>,把不同子类异常(DivideByZeroException、FileOpenException等)统一装进去。因为它们都继承自同一个基类,泛型能保证类型安全,又不丢失具体类型信息。
- 抛出时:各处
throw new XxxException("msg")得到的是具体子类实例 - 收集时:
exceptions.Add(new XxxException(...))自动向上转型为基类引用 - 遍历时:哪怕集合里混着多种异常,也能用统一接口访问,比如调用
e.handle()
靠多态虚函数驱动差异化处理
在基类 BaseException 中声明 virtual void Handle(),每个子类重写它。这样,哪怕你用泛型集合遍历所有异常,调用 e.Handle() 时,实际执行的永远是对应子类的逻辑——除零异常记录日志并建议重试,文件异常则提示路径并检查权限。
- 不用 if-else 判断类型,避免硬编码分支
- 新增一种异常?只需新增子类+重写 Handle,原集合和遍历代码完全不动
- Handle 内部可结合泛型方法做进一步操作,比如
Log<T>(e)记录带类型标签的日志
借泛型方法统一触发异常流程
把“抛出→捕获→收集→处理”封装成泛型方法,例如:void Process<T>(Func<T> operation) where T : BaseException。传入一个可能抛异常的操作,内部用 try-catch 捕获后加入泛型集合,最后统一调用 Handle。
- 同一份流程代码,适配任意子类异常类型
- 测试时可传入
() => new DivideByZeroException()或() => new NetworkTimeoutException(),观察处理链是否完整 - 配合泛型约束(
where T : BaseException),编译期就防止误传非异常类型
用字典泛型做异常路由表
当需要按场景分发处理时,用 Dictionary<Type, Action<BaseException>> 建立类型到行为的映射。比如:
handlers[typeof(FileOpenException)] = e => ShowFileDialog(e.Message);handlers[typeof(MemoryAllocException)] = e => TriggerGC();- 捕获到异常后:
handlers[e.GetType()](e),自动跳转到对应逻辑 - 这种结构比层层嵌套的 catch 更清晰,也比 switch-type 更易扩展
不复杂但容易忽略:异常本质是对象,泛型集合是它的收纳箱,多态是它的调度器。三者合起来,异常就从“打断程序的意外”变成了“可组织、可追踪、可响应的数据流。

















