主意
我正在考虑使用回调而不是在 C#/.NET 中引发异常。
优点和缺点
优点是
- 没有隐藏的 goto 类似未检查异常的控制流
- 更简洁的代码,尤其是在涉及多个异常的情况下
- 抛出的异常记录在方法签名中,调用者被迫考虑处理异常,但可以轻松地将应用程序范围的异常处理程序、“UnhandledExceptionHandler”或 null 传递给它们。所以它们有点像“软”检查异常,但更易于维护,因为可以通过重载方法之后抛出异常,或者可以通过不再在异常处理程序上调用“handle”来删除异常)。
- 也适用于异步调用
- 异常处理程序可以处理在不同位置抛出的多个异常
- 明确应处理哪些异常。以普通方式抛出异常仍可用于您不想处理的异常,例如“NotImplementedException”。
缺点是
- 不习惯 C# 和 .NET
- throwing 方法必须通过立即返回返回值来中断控制流。如果返回类型是值类型,这很困难。
- ? (见下面的问题)
问题
我可能遗漏了一些关键的缺点,因为我想知道为什么不使用它。我错过了什么缺点?
例子:
代替
void ThrowingMethod() {
throw new Exception();
}
和
void CatchingMethod() {
try {
ThrowingMethod();
} catch(Exception e) {
//handle exception
}
}
我会做
void ThrowingMethod(ExceptionHandler exceptionHandler) {
exceptionHandler.handle(new Exception());
}
void CatchingMethod() {
ThrowingMethod(exception => */ handle exception */ );
}
和
delegate void ExceptionHandler(Exception exception);
在某处定义,并且“handle(...)”是一个扩展方法,用于检查 null、检索堆栈跟踪,如果在抛出异常时根本没有异常处理程序,则可能抛出“UnhandledException”。
在之前没有抛出异常的方法中抛出异常的示例
void UsedToNotThrowButNowThrowing() {
UsedToNotThrowButNowThrowing(null);
}
//overloads existing method that did not throw to now throw
void UsedToNotThrowButNowThrowing(ExceptionHandler exceptionHandler) {
//extension method "handle" throws an UnhandledException if the handler is null
exceptionHandler.handle(exceptionHandler);
}
返回值的方法示例
TResult ThrowingMethod(ExceptionHandler<TResult> exceptionHandler) {
//code before exception
return exceptionHandler.handle(new Exception()); //return to interrupt execution
//code after exception
}
TResult CatchingMethod() {
return ThrowingMethod(exception => */ handle exception and return value */ );
}
和
delegate TResult ExceptionHandler<TResult>(Exception exception);