【发布时间】:2026-02-20 14:40:02
【问题描述】:
当我在 finally 语句的块中放置 return 时,编译器会告诉我:
控件不能离开 finally 子句的主体
例子:
try
{
}
catch
{
}
finally
{
return;
}
这是为什么?
【问题讨论】:
当我在 finally 语句的块中放置 return 时,编译器会告诉我:
控件不能离开 finally 子句的主体
例子:
try
{
}
catch
{
}
finally
{
return;
}
这是为什么?
【问题讨论】:
考虑一下如果你在try 块内return 1 和return 0 在finally 块内会发生什么...你的函数将试图返回两个值! try 和 catch 的组合选项在控制流方面是详尽无遗的。
【讨论】:
这是设计使然,并且在 C# 规范中有所描述:
break、continue或goto语句的编译时错误 将控制权转移出finally块。当break、continue或goto语句出现在finally块中,即语句的目标 必须在同一个finally块内,否则为编译时 发生错误。
return语句的编译时错误 发生在finally块中。
另外,来自C# 6.0 spec draft on MSDN:
return语句出现在finally块中是编译时错误。
【讨论】:
当前的答案解释了为什么这种情况发生得很好,但我也认为重要的是要注意在不涉及返回值的情况下绕过这个约束是多么容易,并且finally 子句是最后一件事在方法中(经常发生):
try {}
catch {}
finally
{
FinallyMethod();
}
然后在FinallyMethod 中,您可以随意使用return 语句
void FinallyMethod()
{
//...
if (x == y)
return;
else
a = b;
//etc.
}
【讨论】:
FinallyMethod 内部返回不会对包含 try/catch/finally 的方法执行任何操作。
FinallyMethod 的return 不会让您从调用站点返回。
if (!x) return; //do a lot of stuff。因此,您可以为此目的在 FinallyMethod 中使用 return,而不是在嵌套的 if 子句下执行所有操作。
finally 块中使用return。
finally 子句(通常是这种情况),然后使用我建议的方法是相当于使用return。我已经在回答中澄清了这一点。