Sco*_*ski 8 c# coding-style exception-handling
这个问题来自针对我创建的对象的代码分析.分析说我应该捕获一个比基本异常更具体的异常类型.
您是否发现自己只使用捕获通用异常或尝试捕获特定异常并使用多个catch块默认为一般异常?
有问题的代码块之一如下:
internal static bool ClearFlags(string connectionString, Guid ID)
{
bool returnValue = false;
SqlConnection dbEngine = new SqlConnection(connectionString);
SqlCommand dbCmd = new SqlCommand("ClearFlags", dbEngine);
SqlDataAdapter dataAdapter = new SqlDataAdapter(dbCmd);
dbCmd.CommandType = CommandType.StoredProcedure;
try
{
dbCmd.Parameters.AddWithValue("@ID", ID.ToString());
dbEngine.Open();
dbCmd.ExecuteNonQuery();
dbEngine.Close();
returnValue = true;
}
catch (Exception ex)
{ ErrorHandler(ex); }
return returnValue;
}
Run Code Online (Sandbox Code Playgroud)
感谢您的意见
编辑:这是代码分析的警告
警告351 CA1031:Microsoft.Design:修改"ClearFlags(字符串,GUID)"捕获超过"异常"更具体的异常或重新抛出异常
Sim*_*ens 25
你应该几乎从不赶上顶级的例外.
在大多数情况下,您应该捕获并处理可能的最具体的异常,并且只有在您可以使用它时才有用.
对此的异常(哈哈)是,如果您正在捕获日志记录并重新抛出异常,那么有时可以捕获顶级异常,记录并重新抛出它.
你应该几乎永远不会捕获顶级异常并吞下它.这是因为如果你正在捕捉一个顶级异常,你真的不知道你在处理什么; 绝对地,任何事情都可能导致它,所以你几乎肯定无法做任何能正确处理每一个失败案例的事情.可能有一些失败,你可能只想静静地处理和吞下,但只要吞下顶级异常,你也会吞下一大堆真的应该向上抛出你的代码来处理更高的问题.在你的代码示例中,你可能想要做的是处理一个SQLException并记录+吞下它; 然后对于异常,记录并重新抛出它.这涵盖了你自己.您仍在记录所有异常类型,但您只能吞下可预测的SQLException,这表明您的SQL /数据库存在问题.
一种常见的做法是,只有每个处理当时可以实际解决的异常,如果您无法在代码中解析它,那么您可以让它向上冒泡.如果您无法在上一级解决它,请允许它继续.如果它未达到顶部,则向用户显示礼貌的应用程序(可能尝试快速自动保存)并关闭应用程序.通常认为允许应用程序在未处理的异常之后继续运行会更糟糕,因为您无法预测应用程序的状态,因为发生了异常情况.最好只关闭并重新启动应用程序以恢复到预期状态.
看看Krzysztof Cwalina的这篇文章,我发现它非常有助于理解何时捕获或忽略异常:
在决定何时捕获,抛出或忽略异常时,它描述的有关设计异常层次结构的所有原则也适用.他将例外分为三组:
DivideByZeroException
,表示代码中的错误; 你不应该处理这些,因为可以通过更改你的代码来避免它们.FileNotFoundException
您需要处理的逻辑错误,因为您不能保证它们不会发生.(即使您检查文件是否存在,它仍然可以在读取之前在该瞬间被删除.)OutOfMemoryException
,您无法避免或处理的系统故障.