9

我已经搜索了我的问题的答案,但找不到答案。抱歉,如果答案在那里并且我正在复制!

我不断看到 try/catch 代码,例如.....

try
{
    //Do whatever
}
catch (Exception ex)
{
    MessageBox.Show("Oops, something went wrong!");
}

这将导致警告 ex is never used。

所以我的问题是......虽然 ex 从未使用过,但声明中有什么好处吗?有人告诉我,它可能会向堆栈跟踪添加细节?有时我会看到 catch(Exception) 停止警告,但这会带来什么好处(如果有的话)?如果我要写这个并且不以任何方式使用异常,我就不会声明 ex...

try
{
    //Do whatever
}
catch
{
    MessageBox.Show("Oops, something went wrong!");
}

不是一个大问题,但肯定知道会很好!

谢谢

弗雷德

4

8 回答 8

10

您可以使用以下模式,仍然声明特定的异常类型,不使用变量,以确保结构化异常处理 (SEH) 仍然发生:

try
{
    //Do whatever
}
catch (IOException)
{
    MessageBox.Show("Oops, something went wrong in the IO!");
}
catch (Exception)
{
    MessageBox.Show("Oops, something went wrong!");
}

这不是我通常会使用的做法,因为如果不重新抛出它,我可能会记录异常详细信息。

于 2012-08-15T09:50:27.597 回答
3

抑制异常通常是不好的形式……让它们向上移动。

关于“添加细节”,重新抛出异常throw以保留堆栈跟踪,否则您将丢失细节。同样,替代方法是根本不抓住它。如果您对异常没有任何用处(恢复、展开等),则很可能没有充分的理由来捕获它。

请参阅:在 C# 中重新引发异常的正确方法是什么?

另请参阅:“回归基础 - 例外”

于 2012-08-15T09:49:28.293 回答
3

请务必注意,您发布的两个代码块存在差异。 catch (Exception ex)只会捕获 CLR 定义的异常(从 派生的异常Exception)。 catch单独将捕获任何东西 - 包括 CLR 尚未捕获或包装自身的非托管异常。

如果你想在不改变代码行为的情况下避免编译器警告,或者如果你想在仍然捕获特定异常类型的同时避免警告,你可以使用它来代替:

catch (Exception)
{
}

这里的好处是您可以具体:catch (SqlException)例如。如果您不使用该变量,则声明发出警告,但特定于类型的行为仍然有用。

无论如何,声明异常不会向信息中添加任何内容(堆栈跟踪或其他),除非您明确地包装和/或重新抛出异常。(顺便说一句,不要使用throw exrethrow,因为这确实会丢失信息:只需使用throw。)

于 2012-08-15T09:49:35.677 回答
1

您可以将该ex变量用于以后使用,包括日志记录、消息传递等。

try
{
    //Do whatever
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);

}

假设您想记录您的异常,以便开发人员稍后可以查看日志并确定出了什么问题。在这种情况下,ex将保存记录所需的所有必要详细信息。例如 StackTrace、Message、InnerException(如果有)等。

对于您的问题:

虽然 ex 从未使用过,但声明中是否有任何好处?

如果您不打算使用,那么声明它没有任何好处。

有人告诉我,它可能会向堆栈跟踪添加细节?

我不确定,但我认为不是。如果您定义一个,那么它将包含异常的堆栈跟踪,但它不会向其中添加任何内容。

有时我会看到 catch(Exception) 停止警告,但这会带来什么好处(如果有的话)?

如果要使用throw关键字重新抛出异常,可以使用catch(Exception)

于 2012-08-15T09:47:21.387 回答
1

如果你真的不想做任何有异常的事情,你也可以这样做以避免编译器警告:

catch (Exception)
{
  // Stick our head in the sand
}

或只是抓住

于 2012-08-15T09:49:52.113 回答
1

这一切都与开发人员和他在以后实施适当的日志记录/调试的能力有关......

这:

catch (Exception ex)
{
    MessageBox.Show("Oops, something went wrong!");
}

可以很容易地转换为

catch (Exception ex)
{
    Log.Append(ex);
    MessageBox.Show("Oops, something went wrong. Please check the Log file.");
}

有时,当您逐行运行时,它只是用于调试MessageBox.Show,您可以在行上设置一个断点并读取ex变量。

它有它的用处,但是,在编译时,如果你不使用它,你会得到一个警告,指出该变量ex已声明但未使用,因此,你可以跟踪所有这些并将其记录或删除它。

再一次,这完全取决于程序员的选择,而且……一个未使用的变量在结束程序上并不是那么成问题。

于 2012-08-15T09:51:57.387 回答
0

不,除非您实际使用它,否则声明它是没有意义的。

于 2012-08-15T09:47:38.993 回答
0

which将Exception ex作为对运行时异常对象的引用可以提供多种优势。作为开发人员,您自己可以将其记录在文本文件中或向自己发送报告。

从 MSDN 的文档开始:

如果要重新抛出当前由无参数 catch 子句处理的异常,请使用不带参数的 throw 语句。

http://msdn.microsoft.com/en-us/library/0yd65esw%28v=vs.80%29.aspx

于 2012-08-15T09:52:20.257 回答