接球与接球(例外 e)和投掷与投掷 e

本文关键字:例外 | 更新日期: 2023-09-27 18:35:44

这两个代码示例是一样的吗? Catch 和 Catch(异常 e)具有相同的输出,如果我编写 ThrowThrow e,结果也相同。

主要:

try
{
    A();
    //B();
}
catch (Exception e)
{
    Console.WriteLine("{0} exception caught.", e);
}

代码 1:

static void A()
{
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch (Exception e)
    {
        throw e;
    }
}

代码 2:

static void A()
{
    // Rethrow syntax.
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch
    {
        throw;
    }
}

接球与接球(例外 e)和投掷与投掷 e

我认为这里有两个问题。


throwthrow e;有什么区别?

我认为没有充分的理由写catch (Exception e) { throw e; }.这将丢失原始堆栈跟踪。使用 throw; 时,将保留原始堆栈跟踪。这很好,因为这意味着更容易找到错误的原因。


catchcatch (Exception e)有什么区别?

你的两个例子都是相同的,同样无用——它们只是捕获一个异常,然后重新抛出它。一个细微的区别是第一个示例将生成编译器警告。

声明变量"e"但从未使用

如果您的 catch 块中有一些其他代码实际上做了一些有用的事情,那么问这个问题更有意义。例如,您可能希望记录异常:

try
{
    int value = 1 / int.Parse("0");
}
catch (Exception e)
{
    LogException(e);
    throw;
}

现在,有必要使用第一个版本,以便对捕获的异常进行引用。

如果您的 catch 块实际上没有使用异常,那么您可能希望使用第二个版本来避免编译器警告。

如果我们忽略"未使用的变量"警告,则唯一一次存在实际差异

catch {...}

catch(Exception ex) {...}

是指某些非 C# 代码引发非Exception异常。C++可以扔任何东西。在.NET 1.1中,您必须使用catch(无(Exception ex))来处理这些异常。然而,这是有问题的——尤其是,你看不到扔了什么!因此,在 .NET 2.0 及更高版本中,默认情况下会将其包装,因此即使C++抛出string,您也会将其视为Exception子类。请注意,这可以通过配置设置禁用,但:不要。别管它!

throw;throw ex;的问题已经提到过,并且与堆栈跟踪有关。您可以在这两种情况下使用 throw,从而保留原始堆栈跟踪。