【问题标题】:Using catch without arguments使用不带参数的 catch
【发布时间】:2011-11-04 13:18:25
【问题描述】:

有什么区别:

catch
{
    MessageBox.Show("Error.");
}

和:

catch (Exception ex)
{
    MessageBox.Show("Error.");
    //we never use ex, so is it better to use catch without arguments?
}

【问题讨论】:

  • 在第二种情况下,如果您想捕获该类型或派生类型的异常,但不想了解详细信息,请使用catch (Exception)。否则你会得到一个警告并在不需要变量时声明一个变量

标签: c# try-catch


【解决方案1】:

从 .NET 2 开始,如果您不调整配置​​?什么都没有。

在那之前,或者通过一些我记不清的配置调整,有可能从非托管代码抛出异常,没有被转换为Exception-兼容对象。

请注意,两者之间还有另一个选项,您可以指定类型但不指定变量:

catch (Exception)
{
   ...
}

就我个人而言,即使没有记录异常,我也会非常警惕。如果您要调用愚蠢的 API,则可能需要它,但通常最好避免。

【讨论】:

  • "有可能从没有得到的非托管代码中抛出异常......" 所以从 2.0 开始,它会转换为兼容异常?即现在任何由托管或非托管抛出的东西都将被 catch (Exception e){} 捕获。顺便说一句,我确实尝试过使用 Outlook 互操作库,但不确定如何获得合法的非托管代码错误。
  • @devanalyst:是的,我相信现在一切都转换为Exception
  • @JonSkeet:但是catchcatch (Exception)catch (Exception ex) 之间有什么区别?第一个什么都不做,只捕捉所有东西,第二个只是类型,第三个也是细节?除了异常,你还应该捕获什么?
  • @testing:你通常会捕获一个 specific 异常类型。根据答案,在 .NET 2.0 之前有一些奇怪的情况,catch(Exception) { } 可能无法捕获所有内容,但catch { } 会,IIRC。但幸运的是,那些日子早已一去不复返了。
【解决方案2】:

我认为它们是相同的。但是第二种情况引发了编译器警告,因为您声明了一个未使用的异常。我更喜欢第一个,因为您明确表示您不使用异常。还有第三个

catch (Exception)
{
    //do something
}

如果你想指定异常的类型但不关心异常本身。

【讨论】:

  • 那么这是否意味着如果抛出异常,它仍然会进入 catch 块内部,即使我们对异常不做任何事情?
  • @PedroGordo 是的
【解决方案3】:

通常您应该首先捕获特定错误。

但是如果你像你一样去抓一个一般的Exception,我会说使用第二种情况:

catch (Exception ex)
{
     MessageBox.Show("Error.");
     //we never use ex, so is it better to use catch without arguments?
}

这可以帮助您进行调试,因为变量包含堆栈跟踪、异常消息...等。您可以使用它来记录错误或帮助您防止错误的东西。

使用这种方法时要非常小心:

MessageBox.Show("Error.");

在某个地方(如日志文件)不跟踪您的错误可能会造成非常大的混乱。

【讨论】:

  • 异常数据还是可以访问的。如果您在没有变量的情况下进入异常,则会出现一个符号,显示异常数据。
  • @GeirGrusom - 是的,但您不能使用该信息登录文件或其他什么可以吗?
  • @GeirGrusom 当然,您可以在调试时看到异常,但您没有引用它来记录或向用户显示适当的消息。
【解决方案4】:

在您的第二个示例中,您可以引用异常数据,例如堆栈跟踪、源代码等。它还提供了有时有用的一般消息。它会告诉您为什么会遇到异常,这在调试时很重要。

【讨论】:

  • 我想你没抓住重点,第一个捕获所有异常,第二个捕获.NET 异常
  • 实际上他们所问的只是两个 catch 示例之间的区别,这就是区别。您要么引用异常,要么不引用。所以你知道,这两个例子都捕获了所有 .Net 异常。您捕获的任何异常都将是“.Net 异常”,因为这是 C#。同样重要的是要注意,所有异常在其继承树中都有 Exception 类,因为异常类必须直接或通过从另一个继承了 Exception 类的类继承来间接继承它。
  • 你错了,有些异常不是继承自Exception。由用户代码或 C# 代码创建的有,但其他一些则没有
  • 我真的很讨厌被卷入你的拖钓,但我明白,为了抛出异常,你必须从 Exception 继承。所以我尝试了你所说的,创建了一个类,然后尝试抛出它的一个新实例。它导致出现此消息“捕获或抛出的类型必须从 System.Exception 派生”的异常。你说的“C# 代码可以做,但其他一些代码不做”到底是什么意思。考虑到您的声誉,我真的很震惊您不知道琐碎的异常处理/行为。
  • jlafay - 再一次,你错了。一些非托管代码(即非 C# 和非 .NET)抛出不是从 Exception 派生的异常。为什么你会认为我在拖钓?
【解决方案5】:

某些异常不能被catch(Exception) 捕获。

在 linux 上的 mono 中出现以下异常,应该在没有参数的情况下捕获。

否则运行时将忽略catch(Exception) 语句。

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

如果遇到这样的问题,请尝试删除catch语句的参数,记录上下文变量以找出错误原因。

附:不知道windows上怎么样,windows下运行的程序是正常的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    相关资源
    最近更新 更多