4

考虑,

        static void Main(string[] args)
        {
            Console.WriteLine(fun());
        }

        static int fun()
        {
            int i = 0;
            try
            {
                i = 1;
                return i;
            }
            catch (Exception ex)
            {
                i = 2;
                return i;
            }
            finally
            {
                i = 3;
            }
        }

示例代码输出“1”。但是在 finally 块中 i 的值更改为 3。为什么'i'的值没有改为3?

谢谢,

4

5 回答 5

12

考虑一下这段代码——我认为这段代码解释了你在想什么,以及如何让你认为应该发生的事情真正发生:

static void Main(string[] args)
{
    int counter = 0;
    Console.WriteLine(fun(ref counter)); // Prints 1
    Console.WriteLine(counter); // Prints 3
}        

static int fun(ref int counter)
{
  try
  {
      counter = 1;
      return counter;
  }
  finally
  {
      counter = 3;
  }
}

使用此代码,您可以从该方法返回 1,但您还将计数器变量设置为 3,您可以从该方法外部访问它。

于 2009-10-26T18:26:33.363 回答
7

您必须记住,finally 在 try 和 catch 中的所有其他内容之后执行。将 return 语句放在 try/catch/finally 语句之后,使其返回 3。

于 2009-10-26T18:22:16.367 回答
3

我想如果你使用引用类型而不是值类型,你会得到不同的行为。

于 2009-10-26T18:46:45.240 回答
2

当您说“return i”时... C# 将该返回值放在临时保存区域(内存)中,然后运行您的“finally”代码...如果 finally 块能够修改该值,它将破坏安全性/finalism 的 finally 块。

这就像一个带有 return 内部的 using 语句......“Dispose”仍然会发生,在 return 之后(可以这么说)。

于 2009-10-26T18:26:12.270 回答
1

finally 总是被执行

无论是否抛出异常,您的代码总是最终执行。所以你的代码实际上应该是:

try
{
    i = 1;
}
catch
{
    i = 2;
}
finally
{
    i = 3;
}
return i;

但在这种微不足道的情况下,finally 块没有多大意义。因为无论在那之前发生了什么,我们总是会返回 3。

finally 用于释放资源

finally当您必须释放块内分配的一些系统资源时,通常应该使用try块(即打开数据库连接,读取try块中的数据并关闭它finally)。因此,无论是否有异常,它们总是会被释放。finally在这种情况下,使用块没有多大意义。

于 2009-10-26T18:33:50.057 回答