首先,免责声明:我有其他语言的经验,但我仍在学习C#的微妙之处
关于问题...我正在看一些代码,它以一种让我关注的方式使用try/catch块.当调用解析例程而不是返回错误代码时,程序员使用以下逻辑
catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e.Message,e); }
这是由调用者捕获的,它抛出相同的错误......
由调用者捕获,它抛出相同的错误......
.....被调用者捕获,抛出同样的错误...
备份大约6个级别.
我认为所有这些catch/throw块都会导致性能问题,或者这是C#下的合理实现吗?
在任何语言下,这都是一个糟糕的设计.
异常被设计为在您可以处理它们的级别捕获.捕获异常,只是再次抛出异常只是浪费时间(这也会导致您丢失有关原始错误位置的有价值信息).
显然,编写该代码的人曾经使用过错误代码,然后切换到异常,却没有真正了解它们是如何工作的.如果在一个级别没有捕获,则异常会自动"冒泡"堆栈.
另请注意,例外情况适用于特殊情况.应该永远不会发生的事情.它们不应该用于正常的有效性检查(即,不要捕获除零异常;检查预先除数是否为零).
根据msdn:性能提示和技巧你可以使用try和catch而没有任何性能问题,直到真正的抛出.
投掷(而非捕获)是昂贵的.
除非你要做一些有用的事情(即转换为更有用的异常,处理错误),否则不要设置catch块.
只需重新抛出异常(不带参数的throw语句),或者更糟糕的是,抛出刚捕获的同一个对象绝对是错误的.
编辑:为避免歧义:
重新抛出:
catch (SomeException) { throw; }
从先前的异常对象创建异常,其中覆盖所有运行时提供的状态(特别是堆栈跟踪):
catch (SomeException e) { throw e; }
后一种情况是抛弃有关异常的信息的毫无意义的方法.并且没有任何东西在捕获区块中投掷之前是毫无意义的.可能更糟糕的是:
catch (SomeException e) { throw new SomeException(e.Message); }
它几乎丢失所有包含的有用状态信息(包括最初抛出的信息).