finally{}有什么用处吗?

8

其他地方所解释的那样,一个空的try语句块也有一定的价值。

try{}
finally
{ 
   ..some code here
}

然而,像下面这样一个空的finally块有什么用处吗?
try
{
   ...some code here
}
finally
{}

编辑:请注意,我实际上没有检查CLR是否针对空的finally{}生成任何代码。


6
我认为它没有任何意义。按照问题中的解释,你说你想在代码中使用空的try和finally块,是为了在线程被终止前执行某些操作。但无论线程是否被终止,空的finally块都不会执行任何操作。 - Marshal
不这么想,finally 块最终没有任何用例。 - Pankaj Parkar
它允许您在不对方法进行任何功能更改的情况下使用try块。为什么有人想要一个没有catchfinallytry块是另一个问题。我不知道。实际上,当finally块为空时,try/finally完全从编译后的CIL中删除。也许在某些复杂的情况下,这样的代码与try之外的代码编译方式不同。我不知道。 - Jakub Lortz
2个回答

7

tryfinally语句块中都没有代码时,finally语句块就是无用的。引自MSDN

通过使用finally语句块,您可以清理在try语句块中分配的任何资源,并且即使try语句块中发生异常,也可以运行代码。

如果finally语句块为空,则意味着您根本不需要此语句块。这还表明您的代码不完整(例如,这是DevExpress代码分析中使用的规则)。

实际上,很容易证明try-finally语句中空的finally块是无用的:

编译一个简单的控制台程序并使用以下代码:

static void Main(string[] args)
{
    FileStream f = null;
    try
    {
        f = File.Create("");
    }
    finally
    {
    }
}

打开已编译的dll文件,在IL反汇编器(或任何其他能够显示IL代码的工具)中查看,你会发现编译器只是简单地移除了try-finally

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldstr      ""
  IL_0005:  call       class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
  IL_000a:  pop
  IL_000b:  ret
} // end of method Program::Main

问题是使用类似于“空try”的“空finally”。并不是他为什么在代码中发现了空的finally。 - Marshal
@Marshal 我已经扩展了答案,更详细地解释了我的观点。我希望现在我的回答更清晰了。 - Sergii Zhevzhyk

1

finally块用于执行无论是否抛出异常都应该发生的逻辑,例如关闭连接等。

因此,空的finally块没有任何用处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接