为什么必须在catch块中的throw语句之前返回语句

sir*_*bay 10 c# computer-science

下面的代码会抱怨

try
{
    session.Save(obj);
    return true;
}
catch (Exception e)
{
    throw e;
    return false;  // this will be flagged as unreachable code
}
Run Code Online (Sandbox Code Playgroud)

而这不会:

try
{
    session.Save(obj);
    return true;
}
catch (Exception e)
{
    return false;
    throw e;
}
Run Code Online (Sandbox Code Playgroud)

我不明白......我以为我的csc101告诉我,return语句应该始终是函数中的最后一个语句,它退出函数并将控制权返回给调用代码.为什么这会违背我教授的逻辑,为什么只有其中一个产生警告呢?

Mar*_*ell 16

return将退出该方法; throw将退出该方法,假设它不在.它只能退出一次!try

所以无论顺序如何 - 第一个 throw/ return有效地结束方法.

但是,作为更一般的反馈:如果意图是在失败时返回false,那么您只需要:

try
{
    session.Save(obj);
    return true;
}
catch
{
    return false;
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,我会说这是错误的代码 - 它隐藏了来自调用者的实际问题,使得调试非常困难.它告诉我们它失败的原因.我会说更好的方法就是让异常泡沫化.在这种情况下,没有任何一点返回true,因为我们永远不会返回false- 并且没有必要抓住异常只是为了重新抛出它.所以整个方法变成:

session.Save(obj);
Run Code Online (Sandbox Code Playgroud)

(没有其他任何要求)


如果您的问题是"为什么只有其中一个产生警告":一个公平的问题,但编译器不需要为您发现它们中的任何一个.也许应该发现它.我怀疑gmcs 发现这一点,并警告它-单声道的编译器是更愿意指出愚蠢.


编辑:按预期,[g] mcs输出:

class Program
{
    static void Main() { }
    static void DoSomething() { }
    bool ReturnFirst()
    {
        try
        {
            DoSomething();
            return true;
        }
        catch
        {
            return false;
            throw; // line 15
        }
    }
    bool ThrowFirst()
    {
        try
        {
            DoSomething();
            return true;
        }
        catch
        {
            throw;
            return false; // line 28
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

对于下面的代码 - 所以它确实将两个用途报告为警告:

try
{
    session.Save(obj);
    return true;
}
catch
{
    return false;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 12

你错了:双方你的例子提高无用代码编译器错误,因为这两个throwreturn标记方法的出口点,并没有进一步的代码被允许超过这一点.

然而,编译器是否允许与否,无论下面的代码throwreturn仍是死了,永远不会得到执行的机会.

(注意:这个问题最初标记为Java,我的第一句话与Java编译器语义有关)

  • 在VS2012中没有,`return - > throw`没有warnig,而`throw - > return`是的. (2认同)