C# 在try块中抛出异常有什么问题吗?

C# 在try块中抛出异常有什么问题吗?,c#,C#,对try catch块进行如下编码是否是一种良好的设计实践?也就是说,在try块中使用throw,然后在catch块中捕获它 try { if (someCondition){ throw new Exception("Go the the associated catch block!"); } } catch(Exception ex) { logError("I was thrown in the try block above"); } 一般

try catch
块进行如下编码是否是一种良好的设计实践?也就是说,在try块中使用
throw
,然后在catch块中捕获它

try
{
  if (someCondition){

      throw new Exception("Go the the associated catch block!");

     }
}

catch(Exception ex)
{
      logError("I was thrown in the try block above");
}

一般来说,如果它是最短的可写方法,那么它的设计也不错。但要注意,投掷一个突袭通常需要大约1毫秒才能抓到。在这方面,这是一个性能问题。

有时您可能想要—例如,如果您使用的是ado.net,它有一个习惯,即将所有内容都作为
SqlException
抛出—您可能希望捕获其中一些内容并对其进行处理,同时将其他内容的处理留给另一个级别。在这种情况下,您必须捕获SqlException,看看您是否能够处理它,如果不能,则重新显示它。

视情况而定,您应该在通常情况下引发异常,最好是您自己的异常,而不是一般的异常。

异常适用于异常情况。不应将其用作流逻辑的控制,但如果确实出现需要处理的边缘情况,则这样做没有错


如果我正在读取的数据不是我所期望的,我会在我的代码中加入一个标记。

这完全取决于您试图实现的目标。总的来说,最好避免过度使用try-catch块,尤其是因为它们速度慢。大量的try-catch块会使您的代码看起来凌乱且难以理解


您需要考虑为什么会抛出异常,是意外错误、bug还是预期错误?如果这是一个预期的错误,那么您应该尝试对其进行编码,而不使用try-catch。

如果someCondition表示一个真正的错误状态,那么是。这没有问题。但是,请不要使用它来控制程序流。没有什么比看到一个可以退出作用域的异常抛出更让我抓狂的了。它还可能影响代码中真实异常的正确处理。

这没什么错。您还可以抛出不同类型的异常,并对每种类型使用不同的捕获。抛出异常并不昂贵。它构造的
可丢弃的
非常昂贵,因为这涉及到捕获堆栈。如果您可以避免这一步骤,例如通过预先分配异常并在多个抛出中共享它,那么这是非常有效的。@MikeSamuel有趣的是,您能提供一个链接到一些示例代码来说明一种很好的方法吗?@ScottChamberlain,我的实现使用异常作为非本地控制权转移,以确保像“每年2月30日”这样的坏情况不会拒绝服务。使用
setStackTrace(新的StackTraceElement[0])
来删除cruft堆栈。@ScottChamberlain,实际上我刚刚意识到这个问题是C#而不是Java。在C#中,情况正好相反。表示“默认情况下,堆栈跟踪是在抛出异常对象之前立即捕获的”,这意味着抛出异常的成本很高,除非有办法覆盖该默认值。@ScottChamberlain,可能如中所述覆盖
StackTrace
属性可以避免StackTrace捕获。