Try-Catch Finally并非所有代码路径都返回值

本文关键字:代码 路径 返回值 Finally Try-Catch | 更新日期: 2023-09-27 18:01:06

以下代码应该在理想的情况下执行标量sql命令:

    public object AsScalar()
    {
        SqlCommand cmd = CreateSqlCommand();
        try
        {
            cmd.Connection.Open();
            return cmd.ExecuteScalar();
        }
        catch (Exception exc)
        {
            log.Error("Exception caught for command: "+_sql, exc);
        }
        finally
        {
            Done(cmd);
        }
    }

然而,我从Visual Studio 2010收到以下错误:

not all code paths return a value   

我认为在try-catch finally中,无论是否捕获到异常,它都会执行finally语句,但事实似乎并非如此。

当try最终工作时没有问题,为什么添加catch子句会导致此错误?

Try-Catch Finally并非所有代码路径都返回值

使用catch子句,如果抛出异常,则捕获它,然后它不是传播到方法之外。。。所以执行将到达try/catch/finally块的末尾,到达方法的末尾,并且不会返回任何东西——哎呀!

当您只有一个try/finally语句时,您会或者进入return语句,抛出一个异常,该异常将从方法中传播出来,这两种情况都很好。

如果您想重新抛出异常,可以使用:

catch (Exception exc)
{
    log.Error("Exception caught for command: "+_sql, exc);
    throw;
}

这将修复编译时错误,因为现在没有办法在不返回值或传播异常的情况下结束方法。然而,我通常不鼓励"log/show/log/throw"链上升到堆栈中——通常情况下,只在顶层日志会更干净,无论什么最终都会捕获异常。如果你想添加更多的上下文,你可以将它添加到现有的异常中(有Exception.Data属性,尽管在我的经验中很少使用它(,也可以将这个异常包装在另一个异常中。

catch块实际上只是记录一条消息。它从不返回任何内容或抛出异常。因此,一个可能的执行路径是抛出异常,记录异常,然后。。。什么都没有得到回报。实际上,finally块将被执行,但那里也没有return语句。

要解决此问题,您可以在catch块内抛出异常或返回null。我应该提到,通常情况下,投掷应该是首选的解决方案。