7

次のようなコードの違いは何ですか:

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();
    }
}

この:

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();
}

この構築では本当に最終的にブロックが必要です。Microsoft がそのような構造を提供したのはなぜですか? 冗長なようです。ではない?

4

5 に答える 5

10

など、処理していない他の例外が発生した場合ArgumentOutOfRangeException、または例外を再スローするか、catch ブロックからラップされた例外をスローする場合を想像してください。

  1. 最初のブロックは、例外が発生したかどうかに関係なく、ファイルが確実に閉じられるようにします。

  2. 2 番目のブロックは、例外が発生しないか発生した場合にのみIOExceptionファイルを閉じます。それ以外の場合は扱いません。

于 2013-11-05T22:03:36.007 に答える
7

キャッチされない例外があっても、最初のブロックはファイルを閉じます。

2 番目のブロックは、例外がない場合、またはスローされた例外がキャッチされた場合にのみ、ファイルを閉じます。

最初のものは、実行がブロックの外に移動する原因となる、、、またはその他のジャンプ構文がtryある場合に、ファイルが閉じられることも保証します。2 つ目はそうではないため、リソースが閉じられない可能性があります。breakgotoreturncontinuetry

于 2013-11-05T22:02:40.380 に答える
2

あなたの例では、コードが 以外の例外をスローした場合System.IO.IOException、クリーンアップ コードの実行は保証されません。ブロックを使用すると、スローされる例外の種類に関係なく、finallyブロック内のコードが実行されます。

于 2013-11-05T22:03:19.040 に答える
1

その場合は冗長です。

たとえば、例外を再スローし、ブロックの後にいくつかのコードを実行したい場合に役立ちます。

try {
  // do something dangerous
} catch(...) {
  // log the error or something
  throw; // let the exception bubble up to the caller
} finally {
  // this always runs
}
// this only runs if there was no exception

もう 1 つの例は、catch が別の理由で例外をスローする可能性がある場合です。

try {
  // do something dangerous
} catch(...) {
  // handle the error
  // log the error, which may cause a different exception
} finally {
  // this runs even if the catch crashed
}
// this only runs if there was no exception, or the code in the catch worked

簡単に言えば、あなたが知らないかもしれない多くの理由でコードがクラッシュする可能性があるため、finally何が起こっても確実に実行されるように、クリーンアップをブロックに入れると便利です。

于 2013-11-05T22:08:48.920 に答える