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
作为一般规则,您不应该捕获异常,除非:
您有一个特定的例外,您可以处理和执行某些操作.但是,在这种情况下,您应该始终检查您是否应该首先考虑并避免例外.
您位于应用程序的顶层(例如UI),并且不希望将默认行为呈现给用户.例如,您可能需要一个带有"请发送给我们您的日志"样式消息的错误对话框.
在以某种方式处理异常后重新抛出异常,例如,如果您回滚数据库事务.
在这个例子中,你为什么要捕捉所有这些不同的类型?在我看来,您的代码可以是:
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)
在框架的.NET 2+中捕获一般异常是完全可以接受的.
- 编辑
你不会这样做的唯一原因是,如果你可以用不同的例外做一些不同的事情.如果你打算一直处理它们,只需抓住一般(或你所追求的特定的,并让其他任何东西上升).