Catch(Exception)
和 Catch(Exception ex)
和有什么不一样。我可以看到两者都给了我预期的输出。那么实际的区别是什么呢?推荐哪一款?
假设代码如下。
int a = 1, b = 0;
try
{
int c = a / b;
Console.WriteLine(c);
}
建议使用以下哪一个 catch 块?它们之间的实际区别是什么?
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
或
catch (Exception)
{
Console.WriteLine("Oh NO!!");
}
嗯,
catch(Exception ex)
与 catch(Exception)
相同,但有一点不同
仅:在catch(Exception ex)
中我们可以访问异常类(错误原因)
实例。通常你需要一个异常类实例来打印出原始的
留言:
try {
...
}
catch (AppServerException e) {
Console.WriteLine("Application server failed to get data with the message:");
Console.WriteLine(e.Message); // <- What's actually got wrong with it
}
如果您不需要异常类实例,例如你打算只是消费 异常,catch(Exception ex) 语法过多,catch(Exception) 是 最好:
try {
c = a / b;
}
catch (DivideByZeroException) {
c = Int.MaxValue; // <- in case b = 0, let c be the maximum possible int
}
最后。 不要捕获一般异常类而不重新抛出:
try {
int c = a / b;
}
catch (Exception) { // <- Never ever do this!
Console.WriteLine("Oh NO!!");
}
你真的想编写“无论发生什么错误(包括来自 CPU 的绿色烟雾)”吗? 发生了只需打印“哦不”并继续”?
异常类的模式是这样的:
tran.Start();
try {
...
tran.Commit();
}
catch (Exception) {
// Whatever had happened, let's first rollback the database transaction
tran.Rollback();
Console.WriteLine("Oh NO!");
throw; // <- re-throw the exception
}
很简单:
实际上使用什么取决于您想要获得关于引发的异常的多少信息。
如果需要在
catch
块内使用异常,请给Exception
命名;否则,请保持匿名。
在某些情况下,
catch
块需要做的不仅仅是简单地显示异常消息。例如,当您捕获特定于应用程序的异常时,您也许能够检查异常对象的其他元素。这是一个假设的例子:
catch (ConnectToServerException cse) {
MessageBox.Show(string.Format(
"Connection to server '{0}' failed. Use a name from the following list: {1}"
, cse.AttemptedConnectionServerName
, string.Join(", ", cse.AllowedServerNames)
));
}
上面的代码假设自定义异常
ConnectToServerException
有一个名为 AttemptedConnectionServerName
的属性,其中包含您尝试连接的服务器的名称,以及一个枚举属性 AllowedServerNames
,其中包含可用服务器的名称。
在某些情况下,您只需要知道刚刚发生了特定类型的异常即可。在这种情况下,您不需要为其提供命名变量。
使用
catch(Exception)
,您只需指定要在该 catch 块中处理的异常类型(在本例中,是引发的任何异常,因此它与 catch
相同)
使用
catch(Exception ex)
,您可以传递引发的实际异常的实例,因此您可以访问异常的属性并使用提供的信息执行某些操作。
Catch (Exception)
做同样的事情,因为它也是一个 Exception
类型。
Catch (Exception ex)
捕获所有异常,此外您还可以通过其引用检索消息。
使用取决于需求,如果你想显示异常消息,你可以使用
ex.Message
,否则Catch (Exception)
就足够了。
区别在于,一个会打印尝试除以零。而另一个会打印哦不!!。
处理异常是一个复杂的问题,取决于应用程序,但这里有一些一般性评论:
一般来说,最好为特定异常提供处理程序:
类似:
catch ({System.DivideByZeroException ex )
{
Console.WriteLine("Ops. I cannot divide by zero." );
}
catch ({System.Exception ex )
{
Console.WriteLine("There was an error during calculations: {0}", ex.Message );
}
迟早你会发现
Console.WriteLine
还不够好,你必须使用记录器,所以最好尽早开始使用它。
类似:
catch ({System.DivideByZeroException ex )
{
Console.WriteLine("Oops. I cannot divide by zero." );
}
catch ({System.Exception ex )
{
Console.WriteLine(GetExceptionMsgs(ex));
}
...in another class...
public static string GetExceptionMsgs(Exception ex) {
if( ex == null ) {
return "No exception = no details";
}
var sb = new StringBuilder();
while( ex != null ) {
sb.AppendLine(ex.Message);
ex = ex.InnerException;
}
return sb.ToString()
}