【问题标题】:Is the finally block pointless? [duplicate]finally 块是没有意义的吗? [复制]
【发布时间】:2016-08-15 03:39:31
【问题描述】:

我正在自学 C#,我正在学习 try、catch 和 finally。我正在使用的书正在讨论 finally 块如何运行,而不管 try 块是否成功。但是,写在 catch 块之外的代码不会运行,即使它不在 finally 中?如果是这样,最后的意义是什么?这是本书提供的示例程序:

class myAppClass
{
    public static void Main()
    {
        int[] myArray = new int[5];

        try
        {
            for (int ctr = 0; ctr <10; ctr++)
            {
                myArray[ctr] = ctr;
            }
        }
        catch
        {
            Console.WriteLine("Exception caught");
        }
        finally
        {
            Console.WriteLine("Done with exception handling");
        }
        Console.WriteLine("End of Program");
        Console.ReadLine();            
    }
}

【问题讨论】:

  • 我建议您查看MSDN article !它很简短,并且有一个很好的例子。
  • 如果你的catch语句被设计为抛出异常,finally块仍然会执行。 catch 块之外的任何东西都不会。
  • 作为最佳实践,您不应该像catch { 这样一般捕获,因为这会删除调用堆栈,但会捕获您可以针对特定情况处理的特定故障。我将此称为“尝试隐藏”,我看到一些开发人员使用它来隐藏错误,因为他们缺乏创建有问题或具有挑战性的代码的技能,特别是不遵循良好实践的代码。

标签: c# .net try-catch-finally


【解决方案1】:

finally 块非常有用,因为它允许您进行资源清理,否则如果遇到异常就不会发生这种情况。

例如(伪)

try {
    open socket
    use socket
} 
// note: no catch for any socket exceptions
finally {
    delete socket  // always executed
}

【讨论】:

  • 你也许应该展示没有 finally 的样子,删除 try 和 catch 中的套接字
【解决方案2】:

finally 块的全部意义在于把你开始的东西包起来。假设你在 try 块中打开了一个缓冲区,你应该在 finally 中关闭它。这是必要的,这样即使发生异常并且您退出尝试,资源也会正确关闭。

try
{
    //Do Something
}
catch
{
    //Catch Something
}
finally
{
    //Always Do This
}

很多时候,catch 语句中的代码要么重新抛出异常,要么跳出当前函数。如果您没有 finally 块,则不会执行“始终执行此操作”调用,即如果 catch 语句中的代码发出 return 或抛出新异常。

【讨论】:

    【解决方案3】:

    finally 块执行在任何一种情况下都需要运行的代码。例如,您经常重新引发异常或以其他方式转到其他代码。如果资源的清理代码不在 finally 块中,则不会执行。您也可以将此代码放在 catch 块中,但无论如何您都会在 try 块之后重复代码。

    【讨论】:

      【解决方案4】:

      这些是finally 有用的场景:

      try
      {
          //Do something
      }
      catch (Exception e)
      {
          //Try to recover from exception
      
          //But if you can't
          throw e;
      }
      finally
      {
          //clean up
      }
      

      通常您尝试从异常中恢复或处理某些类型的异常,但如果您无法恢复,则您没有捕获特定类型的异常,异常将被抛出给调用者,但无论如何都会执行 finally 块。

      另一种情况是:

      try
      {
          //Do something
          return result;
      }
      finally
      {
          //clean up
      }
      

      如果您的代码运行正常并且没有引发异常,您可以从try 块返回并释放finally 块中的任何资源。

      在这两种情况下,如果您将代码放在try 之外,它将永远不会被执行。

      【讨论】:

        【解决方案5】:

        这是一个简单的示例,显示在 catch 块之外编写的代码无论如何都不会运行,即使它不在 finally 中!

        try
        {
            try { throw new Exception(); }
            finally { Console.WriteLine("finally"); }
            Console.WriteLine("Where am I?");
        }
        catch { Console.WriteLine("catched"); }
        

        输出是

        终于
        抓到了

        请阅读MSDN

        【讨论】:

          猜你喜欢
          • 2018-04-27
          • 2010-09-08
          • 1970-01-01
          • 2011-02-06
          • 2011-09-14
          • 2013-03-14
          • 1970-01-01
          • 2012-03-06
          • 2011-12-29
          相关资源
          最近更新 更多