.NET Catch常规异常

Ioa*_*nis 6 .net exception-handling

.NET编程指南声明我们不应该捕获一般异常.我假设以下代码不是很好,因为一般异常类型catch:

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name " + classname + "\n" + ex.Message);
           }
        }
        return obj;
    }
Run Code Online (Sandbox Code Playgroud)

在下面的代码中,我捕获特定的异常但不是所有异常,然后我重新抛出异常,以防异常与非泛型异常.但是,函数"CreateInstance"可能会抛出许多异常(ArgumentNullException,ArgumentException,NotSupportedException,TargetInvocationException,MethodAccessException,MemberAccessException,InvalidComObjectException,MissingMethodException,COMException,TypeLoadException).

捕获所有其他个别例外是否可以接受?或者,还有更好的方法?

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (NotSupportedException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TargetInvocationException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (COMException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TypeLoadException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (InvalidComObjectException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name " + classname + "\n" + ex.Message);
               throw;
           }
        }
        return obj;
    }
Run Code Online (Sandbox Code Playgroud)

Kei*_*ith 12

作为一般规则,您不应该捕获异常,除非:

  1. 您有一个特定的例外,您可以处理和执行某些操作.但是,在这种情况下,您应该始终检查您是否应该首先考虑并避免例外.

  2. 您位于应用程序的顶层(例如UI),并且不希望将默认行为呈现给用户.例如,您可能需要一个带有"请发送给我们您的日志"样式消息的错误对话框.

  3. 在以某种方式处理异常后重新抛出异常,例如,如果您回滚数据库事务.

在这个例子中,你为什么要捕捉所有这些不同的类型?在我看来,您的代码可以是:

try
{
    System.Type oType = System.Type.GetTypeFromProgID(customClass);
    return System.Activator.CreateInstance(oType);
}
catch (Exception ex)
{
    Log.Error("...." + ex.Message);

    //the generic catch is always fine if you then do this:
    throw;
}
Run Code Online (Sandbox Code Playgroud)

所以你的问题是规则(3)的一个例子 - 你想记录一个异常,但是然后继续并将其抛出.

所有不同类型都在那里,以便在某些情况下你知道你可以处理(即案例1).例如,假设您知道有一个可以解决的非托管调用COMException- 那么您的代码将变为:

try
{
    System.Type oType = System.Type.GetTypeFromProgID(customClass);
    return System.Activator.CreateInstance(oType);
}
catch (COMException cex)
{   //deal with special case:
    return LoadUnmanaged();
}
catch (Exception ex)
{
    Log.Error("...." + ex.Message);

    //the generic catch is always fine if you then do this:
    throw;
}
Run Code Online (Sandbox Code Playgroud)


Noo*_*ilk 9

在框架的.NET 2+中捕获一般异常是完全可以接受的.

- 编辑

你不会这样做的唯一原因是,如果你可以用不同的例外做一些不同的事情.如果你打算一直处理它们,只需抓住一般(或你所追求的特定的,并让其他任何东西上升).

  • 我不同意.这将使您的应用程序处于异常状态.您应该只处理可以执行某些操作的异常.简单地记录和继续前进是一个坏主意. (5认同)
  • 我同意.有时候我觉得我们认为这不是极端的一般例外. (3认同)
  • @Noon我同意这一点.但是"如果你打算一直处理它们,只需捕获一般"可以由一个没有经验的程序员解释,可以捕获一般的System.Exception,做一些事情,然后继续执行.如果您不知道要处理的错误类型,最好重新抛出或退出,这可能是一件好事. (2认同)