为什么必须在catch块中的throw语句之前返回语句
下面的代码会抱怨
try { session.Save(obj); return true; } catch (Exception e) { throw e; return false; // this will be flagged as unreachable code }
而这不会:
try { session.Save(obj); return true; } catch (Exception e) { return false; throw e; }
我不明白……我以为我的csc101告诉我,return语句应该始终是函数中的最后一个语句,它退出函数并将控制权返回给调用代码。 为什么这会违背我教授的逻辑,为什么只有其中一个产生警告?
return
将退出该方法; throw
也会退出方法,假设它不在try
。 它只能退出一次!
因此无论顺序如何 – 第一个throw
/ return
有效地结束了该方法。
但是,作为更一般的反馈:如果意图是在失败时返回false,那么您只需要:
try { session.Save(obj); return true; } catch { return false; }
就个人而言,我会说这是错误的代码 – 它隐藏了调用者的实际问题,使得调试非常困难。 它告诉我们它失败的原因 。 我会说更好的方法就是让exception泡沫化 。 在这种情况下,没有任何一点返回true
,因为我们永远不会返回false
– 并且只是为了重新抛出它而没有必要捕获exception。 所以整个方法变成:
session.Save(obj);
(没有其他任何要求)
如果您的问题是“为什么只有其中一个产生警告”:一个公平的问题,但编译器不需要为您发现它们中的任何一个。 也许应该发现它。 我怀疑 gmcs
会发现这个并警告它 – 单声道编译器更愿意指出愚蠢。
编辑:正如预期的那样,[g] mcs输出:
Program.cs(15,13): warning CS0162: Unreachable code detected Program.cs(28,13): warning CS0162: Unreachable code detected
对于下面的代码 – 所以它确实将两个用途报告为警告:
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 } } }
你错了:你的两个例子都引发了死代码编译错误,因为throw
和return
标记了方法的出口点,并且在该点之外不允许进一步的代码。
但是,无论编译器是否允许, throw
或return
下面的代码仍然是死的,永远不会有机会执行。
(注意:这个问题最初标记为Java,我的第一句话与Java编译器语义有关)
因为代码块中的return语句之后的任何代码都将无法访问。
此答案基于C#,可能适用于或不适用于Java。
在这种情况下,您实际上不需要return
语句。 throw
将是该函数的最后一步。
在此示例中, return
和throw
将结束当前函数。 无论你把它们放在哪个方向,然后首先总是阻止第二个可以访问。
注意 : throw
语句何时结束该函数的例外情况是它是否包含在try
块中。 在这种情况下, throw
函数将结束剩余的try
块代码的执行,并移动到最相关的catch
块 – 或者如果catch
不适用则finally
阻塞。
您的代码应如下所示:
try { session.Save(obj); return true; } catch(Exception e) { throw e; }
但是,如果你正在做的只是重新抛出exception,那么无论如何都没有太多的意义。
要专门回答您的唯一问题:
为什么这会玷污我教授的逻辑呢?
那么你的教授是错的,或者你误解了他们
“回归虚假”; 由于“扔e”,在catch块中无法访问 就在它之前。 当代码在catch块中执行时,第一行是throw,这意味着你立即将exception抛出到调用方法,因此任何后续代码都不会被执行。
try { session.Save(obj); return true; } catch(Exception e) { throw e; //Throws exception to calling method return false; //this will be flagged as unreachable code }
我希望这有帮助。