是否可以在C#中更改finally子句中的返回值?

时间:2013-04-16 14:50:10

标签: c# vb.net return

假设您在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

注意:

  1. 请注意,我出于科学的好奇心问这个问题纯粹;显然,像这样的代码非常容易出错并且容易混淆,不应该写。

  2. 请注意,我询问try { var x = "A"; return x; } finally { x = "B"; }。我知道这不会改变返回值I understand why this happens。我想知道是否有 方法通过finally块更改try块内的返回值。

4 个答案:

答案 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;