C#中如何用Dictionary实现异常映射并正确抛出对应自定义异常?
问题分析与解决方案
你的代码无法正常工作,核心有两个问题:
- 字典初始化时,你写的
DbUpdateException、InvalidOperationException是异常类型本身(Type对象),但字典键定义的是Exception实例,类型完全不匹配,连编译都过不了。 - 就算强行用Exception实例当键,不同异常实例默认按引用比较,你捕获到的实例和字典里存的不是同一个,根本查不到对应值。
正确实现方式
方案1:用Type做键,绑定自定义异常创建逻辑
这种方式能保留原异常的错误信息,方便调试:
// 键是异常类型,值是接收原异常、返回自定义异常的委托 Dictionary<Type, Func<Exception, Exception>> myCustomExceptions = new() { { typeof(DbUpdateException), ex => new CustomExceptionX("数据库更新失败", ex) }, { typeof(InvalidOperationException), ex => new CustomExceptionY("无效操作", ex) } }; // catch块中使用 try { // 你的业务代码 } catch (Exception exception) { // 尝试获取匹配的自定义异常创建逻辑 if (myCustomExceptions.TryGetValue(exception.GetType(), out var createCustomEx)) { throw createCustomEx(exception); } // 没有匹配项时,抛出原异常 throw; }
方案2:支持子类异常匹配
如果你的代码可能抛出DbUpdateException的子类,也想映射到对应的自定义异常,可以遍历字典找兼容的类型:
try { // 你的业务代码 } catch (Exception exception) { var match = myCustomExceptions.FirstOrDefault(kv => kv.Key.IsAssignableFrom(exception.GetType())); if (match.Value != null) { throw match.Value(exception); } throw; }
关键提醒
- 抛出自定义异常时,一定要把原异常作为内部异常传入,这样能保留完整的错误调用栈,排查问题更方便。
- 别用
myCustomExceptions[exception]这种直接索引的方式,找不到键时会额外抛出KeyNotFoundException,用TryGetValue或者FirstOrDefault更安全。
内容的提问来源于stack exchange,提问作者user20291437
相关产品推荐
相关产品推荐

