什么';C#中各种try-catch之间的区别是什么
本文关键字:之间 try-catch 区别 是什么 什么 | 更新日期: 2023-09-27 18:02:24
可能重复:
尝试/接球/投掷和尝试/接球(e(/投掷之间的区别
原谅我的愚蠢,有人知道他们之间的区别吗?
try
{
return 1 / 0;
}
catch (Exception)
{
throw;
}
try
{
return 1 / 0;
}
catch
{
throw;
}
try
{
return 1 / 0;
}
catch (Exception e)
{
throw(e);
}
- 将仅捕获并重新引发从
Exception
派生的异常 - 将捕获并重新引发任何异常。(编辑:由于CLRv2,所有异常都是从
Exception
派生的,因此这与1相同。见下面Eric Lippert的评论( - 将捕获从
Exception
派生的任何异常并再次抛出,从而重置异常的堆栈跟踪
没有参数的catch
子句可以捕获任何类型的异常。这有时被称为"一般"捕获条款。您可能永远不应该在生产应用程序中使用它,但我认为它有时可能对调试有用。它看起来像这样:
catch
{
}
catch
子句还可以指定要捕获的特定异常类。您应该在应用程序中始终这样做,因为您只应该捕获您知道如何处理的异常。例如,您可能想要捕获一个DivideByZeroException
;你可以这样做:
catch (DivideByZeroException)
{
}
当然,这会产生副作用,即您无法在catch
块内引用异常类本身,因为您尚未将其分配给变量。如果需要在捕获的异常类的实例上调用属性或方法,则需要在catch
语句中包含一个命名变量。这可能是你最习惯看到的,看起来是这样的:
catch (DivideByZeroException ex)
{
// do something with ex here
}
然后有两种方法来编写throw()
语句,选择哪一种很重要:
第一个看起来像这样:
throw;
它是在没有任何参数的情况下编写的,目的是重新抛出捕获的异常,同时保留堆栈跟踪和尽可能多的关于原始异常的信息
(仍有一些边缘情况会导致您丢失堆栈跟踪,但通常情况下,这是比下面的备选方案更可取的。(第二个选项传递一个异常类的实例作为参数,如下所示:
throw(ex);
或者这个:
throw ex;
此还重新抛出指定的异常,但如上所述,它的缺点是丢失了一些堆栈跟踪信息,这些信息告诉您是哪种方法负责抛出异常。除了抛出在同一方法中创建的新异常对象外,很少会使用此方法。
例如,如果您想捕获一个低级异常,并将其包装在一个新的异常对象中,供高级函数使用,则可以使用此表单。
前两个是等价的。
第三种通常应该避免:它从自己的堆栈帧中重新抛出异常,从而在过程中丢失有关原始帧的信息。
catch (Exception)
-捕获从异常类派生的任何内容
catch (Exception e)
-捕获从Exception类派生的任何内容,并将其分配给变量e,您可以使用该变量。
catch
-接住任何投掷的东西。
示例1和2之间没有区别。两者都重新引发原始异常,并且都捕获通用Exception
。如果您想捕获一个更具体的异常,例如DivisionByZeroException
,您可以使用示例1。
对于最后一个示例,您没有重新抛出异常;但是抛出了与您捕获的相同的异常对象。这会导致异常堆栈跟踪被重新设置到抛出它的位置,这可能是一个问题,因为堆栈跟踪没有指向代码中实际发生错误的位置。
不同之处在于throw e;
将抛出具有不同堆栈跟踪的异常。请参阅此已接受的答案。