Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c语言中捕获特定异常与一般异常#_C#_Exception Handling_Coding Style - Fatal编程技术网

C# 在c语言中捕获特定异常与一般异常#

C# 在c语言中捕获特定异常与一般异常#,c#,exception-handling,coding-style,C#,Exception Handling,Coding Style,这个问题来自对我创建的对象运行的代码分析。分析表明,我应该捕获一个比基本异常更具体的异常类型 您是否发现自己只是使用捕获通用异常,还是尝试捕获特定异常并使用多个捕获块默认为通用异常 有问题的代码块之一如下所示: internal static bool ClearFlags(string connectionString, Guid ID) { bool returnValue = false; SqlConnection dbEngine = new SqlConnection

这个问题来自对我创建的对象运行的代码分析。分析表明,我应该捕获一个比基本异常更具体的异常类型

您是否发现自己只是使用捕获通用异常,还是尝试捕获特定异常并使用多个捕获块默认为通用异常

有问题的代码块之一如下所示:

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;
}
谢谢你的建议

编辑:下面是代码分析中的警告


警告351 CA1031:Microsoft。设计:修改“ClearFlags(字符串,Guid)”以捕获比“exception”更具体的异常,或重新显示异常

您几乎永远不会捕获顶级异常

在大多数情况下,您应该捕获并处理最具体的异常,并且只有在您可以使用它做一些有用的事情时

这个异常(哈哈)是,如果您正在捕获日志并重新抛出异常,那么有时候捕获顶级异常、记录它并重新抛出它是可以的


您几乎不应该捕获顶级异常并将其吞下。这是因为如果您正在捕获顶级异常,您并不真正知道您正在处理什么;绝对地,任何事情都可能导致它,所以你几乎肯定不能做任何事情来正确处理每一个失败案例。可能有一些失败,您可能只是想默默地处理和接受,但通过接受顶级异常,您也将接受一大堆真正应该向上抛出的错误,以便您的代码能够处理更高级别的错误。在您的代码示例中,您可能需要处理SQLException并记录它;然后对于异常,记录并重新显示它。这包括你自己。您仍在记录所有异常类型,但您只接受了相当可预测的SQLException,这表明您的SQL/数据库存在问题

一种常见的做法是只处理在那个点上可以实际解决的每个异常,如果在代码中那个点上不能解决它,则允许它向上冒泡。如果您无法在下一级别解决此问题,请允许它继续向上。如果未经处理到达顶部,则向用户显示礼貌的问候语(可能尝试快速自动保存)并关闭应用程序。通常认为,在发生未处理的异常后,允许应用程序继续运行会更糟糕,因为当发生异常时,您无法预测应用程序的状态。最好关闭并重新启动应用程序,以恢复到预期状态。

您应该从最具体的异常捕获到最少的异常,以便以适当的方式处理事情

例如,如果您发出web请求,您应该首先捕获超时和404之类的信息,然后您可以通知最终用户他们应该重试(超时)和/或检查他们输入的URL


然后,您可以捕获一些不太一般的内容,以防出现更古怪的错误,然后在发生荒谬的事情时,立即返回到仅捕获异常。作为最佳实践,您应该避免捕获异常并使用标志作为返回值

相反,您应该为预期的异常设计自定义异常,并直接捕获这些异常。其他任何事情都应该作为意外的例外出现


在上面的示例中,您可能希望重新显示一个更具体的业务异常。

您应该阅读一篇一般性的论文或谷歌的“结构化异常处理”,更好地了解本主题的全部内容,但一般来说,捕获每个异常都被认为是不好的做法,因为您不知道异常是什么(内存故障、内存不足错误、磁盘故障等)


对于许多未知/意外的异常,您不应该允许应用程序继续。通常,您“捕获”作为对编写catch子句的方法进行分析的结果,toy已经确定,该方法实际上可以创建,并且您可以做一些事情来处理这些异常是做一些类似于记录它的事情,在这种情况下,您应该立即重新显示相同的异常(不管它是什么),以便它可以在堆栈中冒泡到某个通用的“未处理的异常处理程序”它可以向用户显示适当的消息,然后导致应用程序终止。

我同意代码分析工具。我对规则的例外是,我在事件处理程序中捕获一般异常,并且用户可以选择报告错误或忽略它

在您提供的示例中,我认为代码分析是正确的。如果您无法处理特定的异常,那么您根本不应该捕获任何异常,让它冒泡到最高级别。这样,在尝试修复问题时,您可以更轻松地重新创建该问题


通过将连接字符串和ID值添加到异常的数据属性中,并确保它也被记录,您可以使您的示例变得更好。这样,您就有机会重现错误。

看看Krzysztof Cwalina的这篇文章,我发现这篇文章对理解何时捕获或复制异常非常有帮助nore例外情况:

它描述的所有关于设计异常层次结构的原则在决定何时捕获、抛出或忽略异常时也适用。他将异常分为三组:

  • 使用错误,例如
    DivideByZeroException
    ,指示代码中的错误;您不应该处理这些错误,因为更改代码可以避免这些错误
  • 逻辑错误,例如
    FileNotFoundException
    ,您需要处理这些错误,因为您不能保证它们不会发生