两者有什么区别

try { ... }
catch{ throw }

and

try{ ... }
catch(Exception e) {throw new Exception(e.message) }

不管第二个显示的是一条消息。


当前回答

抛出一个新的异常会破坏当前的堆栈跟踪。

扔;将保留原始的堆栈跟踪,并且几乎总是更有用。该规则的例外情况是当您希望将异常包装在自己的自定义异常中时。你应该这样做:

catch(Exception e)
{
    throw new CustomException(customMessage, e);
}

其他回答

最重要的区别是第二个表达式删除了异常的类型。异常类型在捕获异常方面起着至关重要的作用:

public void MyMethod ()
{
    // both can throw IOException
    try { foo(); } catch { throw; }
    try { bar(); } catch(E) {throw new Exception(E.message); }
}

(...)

try {
    MyMethod ();
} catch (IOException ex) {
    Console.WriteLine ("Error with I/O"); // [1]
} catch (Exception ex) {
    Console.WriteLine ("Other error");    // [2]
}

如果foo()抛出IOException,[1]捕获块将捕获异常。但是当bar()抛出IOException时,它将被转换为普通异常,并且不会被[1]捕获块捕获。

Throw用于重新抛出已捕获的异常。如果您想在将异常传递到调用链之前对其做一些事情,这可能很有用。

使用不带任何参数的throw可以为调试目的保留调用堆栈。

第一个保存原始的stacktrace:

try { ... }
catch
{
    // Do something.
    throw;
}

第二个选项允许您更改异常和/或消息和其他数据的类型:

try { ... } catch (Exception e)
{
    throw new BarException("Something broke!");
}

还有第三种传递内部异常的方法:

try { ... }
catch (FooException e) {
    throw new BarException("foo", e);
} 

我建议使用:

如果您想在错误情况下做一些清理,而不破坏信息或添加关于错误的信息,则使用第一种方法。 如果您想添加关于错误的更多信息,则使用第三个。 如果您想隐藏信息(不受信任的用户),则使用第二种方法。

throw重新抛出捕获的异常,保留堆栈跟踪,而throw new exception丢失捕获的异常的一些细节。

通常使用throw本身来记录异常,而不完全处理它。

BlackWasp有一篇很好的文章,标题是c#中抛出异常。

如果您愿意,您可以抛出一个新的异常,并将原始异常设置为内部异常。