C#处理catch块时出错

本文关键字:出错 catch 处理 | 更新日期: 2023-09-27 17:58:10

为什么大多数时候都建议我们不应该陷阱像"Exception"这样的错误,而应该陷阱我们作为开发人员所期望的错误。捕获一般性错误是否会对性能造成影响,或者从最佳实践的角度来看,是否建议这样做?

  try
  {
        // Do something
  }
  catch(Exception e)
  {
        //Log error
  }

C#处理catch块时出错

最佳做法是先捕获特定的异常,然后转到更通用的异常。

异常处理(C#编程指南)

可以链接具有不同异常筛选器的多个catch块在一起捕获块在代码,但对于每个异常只执行一个catch块抛出。指定确切类型或基的第一个catch块抛出异常的类被执行。如果没有指定catch块匹配的异常筛选器,没有筛选器的catch块如果语句中存在,则选中重要的是定位具有最特定(即派生)异常类型

对于您的问题:

为什么大多数时候都建议我们不要犯这样的错误"异常",但陷阱错误,我们期待作为开发人员。

一个例子是捕获NullReferenceException。捕获NullReferenceException从来都不是更好的做法,相反,在使用其实例成员之前,应该始终检查对象是否为null。例如字符串。

string str = null;
try
{
   Console.WriteLine(str.Length)
}
catch(NullReferenceException ne)
{
    //exception handling. 
}

相反,应该对null进行检查。

if(str != null)
   Console.WriteLine(str.Length);

编辑:

我想我错了,如果你问哪个异常应该被捕获,哪个不应该,那么IMO,那些可以处理的异常应该被捕捉,剩下的应该留在图书馆,这样它们就可以冒泡到上层,在那里可以进行适当的处理。一个例子是违反主键约束。如果应用程序正在接受用户的输入(包括主键),并且该日期正在插入数据库,则可以捕获该异常,并向用户显示一条消息"记录已存在",然后让用户输入一些不同的值。

但是,如果异常与外键约束有关(例如,下拉列表中的某个值被认为是无效的外键),则该异常应该出现,并且通用异常处理程序应该将其记录在适当的位置。

例如,在ASP.Net应用程序中,这些异常可以记录在Application_Error事件中,并且可以向用户显示常规错误页面。

第2版:OP评论:

如果处于低水平,如果捕获一般错误,而不知道错误是否为sqlexception

即使有任何性能差异,也应该可以忽略不计。但是捕获特定的异常,如果您知道异常将是SqlException,那么捕获它。

您应该只捕获您可以处理的异常。Exception太通用了,所以大多数时候你不能说你可以处理它。这有点有趣,但你应该只捕捉到你除了的例外:)

有些情况下,你需要捕捉Exception,但很少见,大多数时候你应该避免。通常它表示一些设计问题。

查看Eric Lippert的博客(Vexing异常),了解处理异常的最佳方法。

•不要捕获致命异常;不管怎样,你对它们无能为力,而试图这样做通常会让情况变得更糟。

•修复您的代码,使其永远不会触发骨头异常–"索引超出范围"异常永远不会发生在生产代码中。

•通过调用那些在非异常情况下抛出的令人烦恼的方法的"Try"版本,尽可能避免令人烦恼的异常。如果无法避免调用一个令人烦恼的方法,请捕获其令人烦恼的异常

•始终处理指示意外的外部条件的异常;通常,预测每一个可能的失败都是不值得的,也不实用。只需尝试该操作并做好处理异常的准备。

经常使用异常处理实际上是一种懒惰的编程方式。假设您有一个DataTable,并且您想访问第一行。

public DataRow AccessFirstRow(DataTable dt)
{
  try
  {
    return dt.Rows[0];
  }
  catch (Exception e)
  {
    //There isn't a first row or dt is null
  }
}

代替

public DataRow AccessFirstRow(DataTable dt)
{
  if(dt != null)
   if(dt.Rows.Count > 0)
     return dt.Rows[0];
  //If we can't access dt, then don't
  return null;
}

我的经验法则是:

例外情况只能在例外情况下使用。

如果你决定处理它们,就像前面提到的那样,处理你知道可能会遇到的特定异常,而不是一般异常。

这是一个最佳实践。这个想法是,您应该快速明确地处理已知的异常,同时在程序的更高级别上拥有更通用的异常,因为意外异常可能是由一些更主要/根本的错误引起的。

捕获您想要处理的异常。您通常希望在这样的上下文(方法)中处理特定的异常,即您有足够的信息来处理报告的错误(例如,访问用于清理的对象)。

如果try块中的代码抛出不同类型的异常,您可能希望在同一方法中处理一些异常,然后重新抛出其他异常,以便在调用方方法中处理它们(因为在该上下文中,您有处理这些异常的资源)。