C# - 在不将其设置为变量的情况下重新抛出异常

Ort*_*iga 6 c# exception-handling

正如大家所知,在c#中捕获并重新抛出异常这种方式是邪恶的,因为它会破坏堆栈跟踪:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException ex)
{
    throw ex;
}
Run Code Online (Sandbox Code Playgroud)

在不丢失堆栈跟踪的情况下重新抛出异常的正确方法是:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException ex)
{
    throw;
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是我得到了很多编译警告:"变量'ex'被声明但从未使用过".如果你有很多这些,可能会在垃圾中隐藏一个有用的警告.那就是我做的:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException)
{
    throw;
}
catch(AnotherException ex)
{
    //handle it
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但我想知道重新抛出未设置为变量的异常是否有任何缺点..net如何威胁这个?

提前致谢

编辑: 我已经改变了我的代码,以便更清楚我想做什么,因为有些人误解了

Mat*_*eer 7

这没有任何缺点.您只是告诉编译器"我计划捕获此异常,但我不需要引用实际异常",它不会影响抛出的方式或异常的工作方式.你的后一个例子是做你想做的事情的理想方式,但是如果你只是立即throw;在块中没有任何其他东西,那么为什么要抓住呢?


Cod*_*ray 7

我想知道重新抛出未设置为变量的异常是否有任何缺点.

不,没有任何缺点.只有在您想在代码中引用异常时才需要变量,但由于您不需要使用throw语句,因此根本不需要变量.

在尝试消除"嘈杂"编译器警告时,您有正确的想法.他们埋葬你重要的错误倾向想解决,并得到一个干净的构建始终是重要的.最好的解决方案是简单地重写代码以使用无参数catch子句.

但是,请注意,在我看到的82%的情况下,编写完全使用的代码是错误的throw.您通常不应该捕获您不知道如何处理的异常并且只是计划重新抛出.有些情况甚至使用throw可以重置调用堆栈,导致您丢失重要的调试信息.还有更好的替代方法可以记录捕获/重新抛出的异常.您可以在以下问题的答案中找到更多信息:


Don*_*nut 5

如果你没有DummyExceptioncatch块中做任何事情(你不能,因为你没有给它一个标识符),为什么不try/catch完全摆脱该块?例如,只需这样做:

throw new DummyException();
Run Code Online (Sandbox Code Playgroud)

虽然在那时,我可能会评估您在此处要完成的任务,并重新考虑您的应用程序架构,以免以这种方式依赖异常传播.