无论finally块中的内容是什么,它总是被执行(几乎),那么将代码封闭到它或不封闭它之间有什么区别呢?


当前回答

我将用一个文件读取器例外的例子来解释finally的使用

最后不用了

尝试{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine (strReader.ReadeToEnd ()); StreamReader.Close (); } catch(例外ex) { Console.WriteLine (ex.Message); }

在上面的例子中,如果名为Data.txt的文件丢失,将抛出一个异常并将被处理,但是名为StreamReader.Close()的语句;永远不会被执行。 因此,与reader相关的资源从未被释放。

为了解决上述问题,我们使用最后

strReader = null; 尝试{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine (strReader.ReadeToEnd ()); } catch(异常ex){ Console.WriteLine (ex.Message); } 最后{ if (strReader != null){ StreamReader.Close (); } }

快乐编码:)

注意: “@”用于创建逐字字符串,避免出现“Unrecognized转义序列”错误。 符号@意味着从字面上读取该字符串,而不解释控制字符。

其他回答

假设您需要将光标设置回默认指针,而不是等待(沙漏)光标。如果在设置光标之前抛出异常,并且没有完全崩溃应用程序,则可能会留下一个令人困惑的光标。

我将用一个文件读取器例外的例子来解释finally的使用

最后不用了

尝试{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine (strReader.ReadeToEnd ()); StreamReader.Close (); } catch(例外ex) { Console.WriteLine (ex.Message); }

在上面的例子中,如果名为Data.txt的文件丢失,将抛出一个异常并将被处理,但是名为StreamReader.Close()的语句;永远不会被执行。 因此,与reader相关的资源从未被释放。

为了解决上述问题,我们使用最后

strReader = null; 尝试{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine (strReader.ReadeToEnd ()); } catch(异常ex){ Console.WriteLine (ex.Message); } 最后{ if (strReader != null){ StreamReader.Close (); } }

快乐编码:)

注意: “@”用于创建逐字字符串,避免出现“Unrecognized转义序列”错误。 符号@意味着从字面上读取该字符串,而不解释控制字符。

如文档中所述:

catch和finally的一个常见用法是在try块中获取和使用资源,在catch块中处理异常情况,并在finally块中释放资源。

同样值得一读的是:

一旦找到匹配的catch子句,系统就准备将控制转移到catch子句的第一个语句。在catch子句开始执行之前,系统首先按顺序执行所有与try语句关联的finally子句,这些语句的嵌套比捕获异常的语句嵌套多。

因此很明显,即使前面的catch子句有return语句,驻留在finally子句中的代码也将被执行。

有时您不想处理异常(没有catch块),但希望执行一些清理代码。

例如:

try
{
    // exception (or not)
}
finally
{
    // clean up always
}

使用try-finally的大多数优点已经指出了,但我想再加上这一点:

try
{
    // Code here that might throw an exception...

    if (arbitraryCondition)
    {
        return true;
    }

    // Code here that might throw an exception...
}
finally
{
    // Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}

这种行为使它在各种情况下都非常有用,特别是当您需要执行清理(处置资源)时,尽管在这种情况下使用块通常更好。