try {..} catch {...}与最终和没有它之间的区别

Kub*_*ski 6 c# try-catch try-catch-finally

这样的代码有什么区别:

string path = @"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
    file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
    Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}

finally
{
    if (file != null)
    {
        file.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

还有这个:

string path = @"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
    file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
    Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
if (file != null)
{
    file.Close();
}
Run Code Online (Sandbox Code Playgroud)

在这个结构中真的最终是必要的.微软为何提供此类构建?这似乎是多余的.不是吗?

p.s*_*w.g 9

想象一下,如果发生了一些你没有处理过的其他异常,例如ArgumentOutOfRangeException,或者你想重新抛出异常或者从catch块抛出一个包装异常:

  1. 无论是否发生异常,第一个块都将确保文件被关闭.

  2. 如果没有发生异常或发生异常,则第二个块关闭文件IOException.它不处理任何其他情况.


Ser*_*rvy 6

即使存在未捕获的异常,第一个块也将关闭该文件.

仅当没有异常或者捕获到任何抛出的异常时,第二个块才会关闭文件.

第一还将确保,如果文件被关闭try具有break,goto,return,continue,或任何其它跳跃构建体,将导致执行到外部的移动try块.第二个没有,因此可能导致资源未被关闭.