再试一次神秘

时间:2009-10-26 18:18:08

标签: c# try-catch finally

考虑,

        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”。但是i的值在finally块中变为3。为什么'i'的值没有改为3?

谢谢,

5 个答案:

答案 0 :(得分: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,您可以从方法外部访问该文件。

答案 1 :(得分:7)

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

当你说“返回i”时...... C#将该返回值放在临时保存区域(内存)中然后运行你的'finally'代码...如果finally块能够修改该值,它会打败了最后一块的安全/终极。

这就像一个带有返回内容的使用声明......“Dispose”仍然会在返回之后发生(可以这么说)。

答案 4 :(得分:1)

最后总是执行

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

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

但在这个微不足道的案例中,最终阻止不会有多大意义。因为无论之前发生了什么,我们总会返回3。

最后用于释放资源

当你必须释放finally块内分配的一些系统资源时,通常应该使用

try块(即在try块中打开数据库连接读取数据并关闭它finally)。所以无论是否有例外,他们都会被释放。在这种情况下,使用finally阻止没有多大意义。