【发布时间】:2010-12-11 22:38:21
【问题描述】:
使用有什么区别
catch(Exception ex)
{
...
throw ex;
}
并使用
catch // might include (Exception)
{
...
throw;
}
【问题讨论】:
标签: c#
使用有什么区别
catch(Exception ex)
{
...
throw ex;
}
并使用
catch // might include (Exception)
{
...
throw;
}
【问题讨论】:
标签: c#
好吧,第一个将删除堆栈跟踪,并将其替换为您的 throw 所在的位置。第二个将抛出异常而不改变堆栈跟踪。
此外,“catch”将捕获抛出的任何东西,无论它是否是异常。
第二个其实相当于做“catch(object)”。
【讨论】:
第一个重置抛出异常中的堆栈跟踪属性
【讨论】:
throw ex 从该点重新抛出异常对象。这通常很糟糕,因为它破坏了导致原始问题的有用调用堆栈信息。
throw 释放原始捕获的异常,从它实际抛出的那一点开始。它将调用堆栈信息保留到该点,而不是您捕获的点。
catch(Exception) 和catch 本质上是一样的,除了显然第一个给你异常对象做某事,而第二个没有。但两者都会捕获所有异常。它们与catch(SomeKindOfException) 不同,后者只会捕获该特定类型(或更具体的从该类型派生的类型)的异常。这最适合以下情况:
try
{
//some file operation
}
catch(FileNotFoundException fnfex)
{
//file not found - we know how to handle this
}
//any other kind of exception,
//which we did not expect and can't know how to handle,
//will not be caught and throw normally
【讨论】:
据我所知,这是一回事(使用 Exception.. 因为所有异常都派生自该类)。当您仅捕获 Exception 的一个孩子时,它会变得不同......或者当您有几个“捕获”捕获不同的孩子时。 也可能是您捕获了异常,修改了消息,然后将其丢弃。
【讨论】:
throw ex 很糟糕,因为它破坏了调用堆栈。
在框架 1.x 中使用不带参数的 catch 来捕获非托管代码引发的异常非常有用。从框架版本 2 (IIRC) 开始,所有非托管异常都包装在托管 Exception 对象中,因此不再使用无参数捕获。
无参数 throw 并不特定于无参数 catch,它可以在任何 catch 块中使用。不同之处在于,当使用throw; 追溯异常时,它不会覆盖最初引发异常时的堆栈跟踪,因此这是重新引发异常的正确方法。
您应该抛出一个新创建的异常,其中包含您要添加的信息,而不是在 catch 块中使用 throw ex;,并将原始异常作为内部异常。这样一来,您既可以得到最初的失败点,也可以得到抓住它并重新抛出它的点。
因此,您绝不应该在问题的示例中使用任何一种组合。您总是指定异常类型,或者只是追溯异常:
catch (Exception ex) {
...
throw;
}
或者你抛出一个带有内部异常的新异常:
catch (Exception ex) {
...
throw new ApplicationException("Ooops!", ex);
}
请注意,您应该很少捕获 Exception 基类,而是更具体的异常类,它适合您预期的错误。捕获您不知道如何处理的异常通常是没有意义的。
【讨论】: