8

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!!");
}
4

6 回答 6

5

好吧,这与只有一个区别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
  }
于 2013-08-11T16:16:14.750 回答
3

这很简单:

  • 在第一个代码中,您可以捕获异常并获取表示它的对象,这样您就可以获得有关发生的事情的更多信息
  • 在第二个代码中,您只知道引发了异常,但您没有关于它的更多信息。

使用什么实际上取决于您希望获得多少关于引发的异常的信息。

于 2013-08-11T15:00:33.253 回答
2

如果需要在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使用可用服务器名称调用的枚举属性。

在某些情况下,您只需要知道某个特定类型的异常刚刚发生。在这种情况下,您不需要为其提供命名变量。

于 2013-08-11T15:00:49.223 回答
0

不同之处在于将打印尝试除以零。另一个会打印哦,不!.

处理异常是一个复杂的问题,取决于应用程序,但这里有一些一般性评论:


一般来说,最好为特定异常提供处理程序:

就像是:

 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()
}
于 2013-08-11T15:24:39.470 回答
0

Catch (Exception)做同样的事情,因为它也是一种Exception类型。

Catch (Exception ex)捕获所有异常,此外您可以通过其引用检索消息。

使用取决于要求,如果您想显示异常消息,您可以使用ex.Message其他工具Catch (Exception)就足够了。

于 2013-08-11T15:01:42.433 回答
0

catch(Exception)你只需要指定你将在那个 catch 块中处理什么样的异常(在这种情况下,任何引发的异常,所以它与 just相同catch

随着catch(Exception ex)您传递引发的实际异常的实例,因此您可以访问异常的属性并使用提供的信息执行某些操作。

于 2013-08-11T15:05:38.793 回答