6

假设您有一个 C# 方法,其中包含一个块return内的语句。try是否可以修改finally块中的返回值?

return在块中使用的明显方法finally不起作用:

String Foo()
{
    try
    {
        return "A";
    }
    finally
    {
        // Does not compile: "Control cannot leave the body of a finally clause"
        return "B";
    }
}

有趣的是,这可以在 VB 中完成:ReturninsideFinally是被禁止的,但我们可以滥用这样一个事实(可能是出于向后兼容性的原因)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"; }. 我知道这不会改变返回值,并且我理解为什么会发生这种情况。我想知道是否有办法通过 finally 块更改 try 块内设置的返回值。

4

4 回答 4

21

假设您在 try 块中有一个带有 return 语句的 C# 方法。是否可以修改 finally 块中的返回值?

不。

但是,您可以在 finally 块之外修改返回值:

static int M()
{
    try
    {
        try
        { 
            return 123;
        }
        finally
        {
            throw new Exception();
        }
    }
    catch
    {
        return 456;
    }
}

仅仅因为最初有一个“返回 123”并不意味着该方法将返回 123,如果这就是你的问题实际得到的。此方法返回 456。

于 2013-04-16T14:52:35.337 回答
0

VB.NET 版本滥用了 VB6 时代的残留构造,在该构造中,您通过将值分配给函数名称来返回值。

真正有趣的是,在使用标准return语句时生成的 IL 是否存在差异myFunc = "B",因为try...catch...finally语义似乎表明不可能更改return语句返回的值。

于 2013-04-16T15:15:29.193 回答
-1

您可以执行以下操作来达到相同的效果:

private string myFunction()
{
    string result = String.Empty;
    try
    {
        //..
        result = "something";
    }
    finally
    {
        result = "something else";
    }
    return result;
}
于 2013-04-16T14:54:02.987 回答
-1

与引用的 VB 方法的一个密切类比是将修改后的值分配给 by 使用的变量return(这有利于保持单点返回控制):

string returnResult;

try
{
    returnResult = "A";
}
finally
{
    returnResult = "B";
}

return returnResult;
于 2013-04-16T14:54:11.597 回答