假设您在return
块中有一个带有try
语句的C#方法。是否可以修改finally
块中的返回值?
使用return
块中finally
的显而易见的方法无效:
String Foo()
{
try
{
return "A";
}
finally
{
// Does not compile: "Control cannot leave the body of a finally clause"
return "B";
}
}
有趣的是,这个可以在VB中完成:Return
内的Finally
是被禁止的,但是我们可以滥用这个事实(可能出于向后兼容的原因)VB仍然允许通过将返回值赋值给方法名称来修改返回值:
Function Foo() As String ' Returns "B", really!
Try
Return "A"
Finally
Foo = "B"
End Try
End Function
注意:
请注意,我出于科学的好奇心问这个问题纯粹;显然,像这样的代码非常容易出错并且容易混淆,不应该写。
请注意,我不询问try { var x = "A"; return x; } finally { x = "B"; }
。我知道这不会改变返回值I understand why this happens。我想知道是否有 方法通过finally块更改try块内的返回值。
答案 0 :(得分:18)
假设您在try块中有一个带有return语句的C#方法。是否可以修改finally块中的返回值?
没有
但是,您可以修改finally块之外的返回值:
static int M()
{
try
{
try
{
return 123;
}
finally
{
throw new Exception();
}
}
catch
{
return 456;
}
}
仅仅因为最初有一个“返回123”并不意味着该方法将返回123,如果那是你的问题实际上得到的。此方法返回456。
答案 1 :(得分:0)
VB.NET版本滥用VB6时代的残留构造,通过将值赋值给函数名称来返回值。
真正有趣的是,使用标准return
语句而不是myFunc = "B"
语句时产生的IL是否存在差异,因为try...catch...finally
语义看起来似乎规定不可能改变return
语句返回的值。
答案 2 :(得分:-1)
您可以执行以下操作以达到相同的效果:
private string myFunction()
{
string result = String.Empty;
try
{
//..
result = "something";
}
finally
{
result = "something else";
}
return result;
}
答案 3 :(得分:-1)
与引用的VB方法类似的是将修订后的值分配给return
使用的变量(这样可以保留单点控制点):
string returnResult;
try
{
returnResult = "A";
}
finally
{
returnResult = "B";
}
return returnResult;