我一直在帮助同事在他们的代码中调试一些奇怪的行为.以下示例说明了这一点:
static void Main(string[] args)
{
string answer = Sample();
Console.WriteLine(answer);
}
public static string Sample()
{
string returnValue = "abc";
try
{
return returnValue;
}
catch (Exception)
{
throw;
}
finally
{
returnValue = "def";
}
}
Run Code Online (Sandbox Code Playgroud)
这个样本有什么回报?
你认为因为finally块,它返回"def",但事实上,它返回"abc"?我已经逐步完成了代码并确认了finally块实际上已被调用.
真正的答案是你不应该首先编写这样的代码,但我仍然对这种行为感到困惑.
编辑:根据一些答案澄清流程.
当您单步执行代码时,finally将在返回之前执行.
Rob*_*Day 12
你的"finally"块正在为returnValue赋值,而不是实际返回一个值.在finally块更改值之前已经发生了"返回",因此返回"abc".
虽然代码令人困惑,因为你所做的事情没有意义,但它所做的是正确的.
是的,finally 块在函数返回后运行,但这并不重要。请记住,返回值是按值传递的,因此在返回时会为其创建一个新的临时变量,因此finally 块不会影响实际的返回值。如果您想支持所需的行为,您可以使用 out 参数,如下所示:
static void Main(string[] args)
{
string answer;
Sample(out answer);
Console.WriteLine(answer);
}
public static void Sample(out string answer)
{
try
{
answer = "abc";
return;
}
catch (Exception)
{
throw;
}
finally
{
answer = "def";
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以简单地将 return 语句移到 try 块之外,如下所示:
static void Main(string[] args)
{
string answer = Sample();
Console.WriteLine(answer);
}
public static string Sample()
{
string returnValue;
try
{
returnValue = "abc";
}
catch (Exception)
{
throw;
}
finally
{
returnValue = "def";
}
return returnValue;
}
Run Code Online (Sandbox Code Playgroud)
然而,考虑到finally块总是会覆盖返回值,这是一个有问题的设计。