【问题标题】:try finally mystery最后尝试神秘
【发布时间】:2010-12-10 05:33:00
【问题描述】:

考虑一下,

        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?

谢谢,

【问题讨论】:

  • @Joe - 我搜索过。但我没能找到。谢谢。
  • @mahesh,只需单击他评论中提供的 ling Joe。
  • @Mark - 我的意思是“在发布这个问题之前,我搜索了 SO”。

标签: c# try-catch finally


【解决方案1】:

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

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,您可以从方法外部访问它。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我们不能从 finally 返回,因为它给出了错误“控制不能离开 finally 子句的主体”
    • @Steve - 凯文修改了他的答案
    【解决方案3】:

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

    【讨论】:

    • 没错,但真正的问题是:在 try/catch/finally 中的什么时候,对于非引用参数,返回值会被压入堆栈?
    • +1。我认为这是一个很好的观点。我希望我也把它放在我的答案中!
    【解决方案4】:

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

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

    【讨论】:

    • +1 就是这样。我正要发布简单的“因为退货已经发生”,但这个答案几乎就在那里。
    【解决方案5】:

    最后总是被执行

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

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

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

    最后用来释放资源

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

    【讨论】:

    • 我会请投票给我答案 -1 的人澄清他们的决定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    相关资源
    最近更新 更多