.net Catch(Exception)和Catch(Exception ex)的区别

6ioyuze2  于 2023-10-21  发布在  .NET
关注(0)|答案(6)|浏览(166)

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

91zkwejq1#

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
  }

最后。* 不要在没有重新抛出的情况下捕获一般的Exception类 *:

try {
    int c = a / b;
  }
  catch (Exception) { // <- Never ever do this!
    Console.WriteLine("Oh NO!!");
  }

你真的想编码“无论发生了什么错误(包括CPU的绿色烟雾),只要打印出”哦,不“并继续”吗?
Exception类的模式类似于这样:

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
  }
vojdkbi0

vojdkbi02#

很简单

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

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

mfuanj7w

mfuanj7w3#

如果您需要在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,其中包含可用服务器的名称。
还有一些情况,您需要知道的只是发生了特定类型的异常。在这种情况下,不需要为它提供命名变量。

yfwxisqw

yfwxisqw4#

对于catch(Exception),您只需要指定要在catch块中处理的异常类型(在本例中,是任何引发的异常,因此它与catch相同)
使用catch(Exception ex),您可以传递一个实际异常的示例,这样您就可以访问异常的属性并使用提供的信息执行某些操作。

nuypyhwy

nuypyhwy5#

Catch (Exception)做同样的事情,因为它也是Exception类型。
Catch (Exception ex)捕获所有异常,此外,您可以通过其引用检索消息。
使用取决于需求,如果你想显示异常消息,你可以使用ex.Message,否则Catch (Exception)就足够了。

yvgpqqbh

yvgpqqbh6#

不同的是,一个将打印 * 尝试除以零。* 和其他将打印 * 哦不!!*.
处理异常是一个复杂的问题,取决于应用程序,但这里有一些一般性的评论:
一般来说,最好为特定的异常提供处理程序:
例如:

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()
}

相关问题