finally を使用してクリーンアップ コードを実行する方法
finally
ステートメントの目的は、例外がスローされた場合でも、オブジェクト (一般に外部リソースを保持しているオブジェクト) に対して必要なクリーンアップをすぐに実行できるようにすることです。 次のように、共通言語ランタイムによってオブジェクトがガベージ コレクションされるまで待機するのではなく、オブジェクトを使用した後すぐに FileStream で Close を呼び出すというのも、このようなクリーンアップの一例です。
static void CodeWithoutCleanup()
{
FileStream? file = null;
FileInfo fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
例
上のコードを try-catch-finally
ステートメントに変えるには、次のようにクリーンアップ コードを作業コードから切り離します。
static void CodeWithCleanup()
{
FileStream? file = null;
FileInfo? fileInfo = null;
try
{
fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
finally
{
file?.Close();
}
}
try
ブロック内では OpenWrite()
呼び出しの前のどの時点でも例外が発生する可能性があり、また、OpenWrite()
呼び出し自体が失敗するおそれもあるため、ファイルを閉じようとしたときに、それが開いているという保証はありません。 finally
ブロックによって、Close メソッドを呼び出す前に、FileStream オブジェクトが null
でないことを確認するチェックが追加されます。 この null
チェックがないと、finally
ブロックからその NullReferenceException がスローされる可能性がありますが、finally
ブロックにおける例外のスローはできるだけ回避する必要があります。
データベース接続も、finally
ブロックで閉じられる対象になります。 データベース サーバーで許可される接続数は限られていることがあるため、データベース接続はできるだけ早く閉じる必要があります。 接続を閉じる前に例外がスローされる場合は、ガベージ コレクションを待機するより、finally
ブロックを使用することをお勧めします。
関連項目
.NET