C#のtry-finallyのみを使った例外処理のパターンを徹底解説!初心者向け入門ガイド
生徒
「C#でエラーが起きたときに、必ず後始末をする方法ってありますか?」
先生
「はい、C#にはtry-finallyという仕組みがあって、エラーの有無に関係なく必ず実行したい処理を書くことができます。」
生徒
「それって、例えばファイルを閉じたり、片付けをする処理とかですか?」
先生
「その通りです!では、具体的にtry-finallyの基本的な使い方を見ていきましょう。」
1. try-finallyとは?
C#のtry-finally構文は、例外(プログラム中で起きるエラーのこと)が発生しても、最後に必ず実行してほしい処理を指定するための仕組みです。通常、例外処理といえばtry-catchを思い浮かべる人が多いですが、try-finallyだけを使う場合もあります。
例えば、料理をするときに「途中で失敗しても、後片付けだけは必ずやる」というイメージです。プログラムの世界でも同じように、エラーが起きてもファイルを閉じたり、接続を切ったりする必要があります。そのときに役立つのがtry-finallyです。
2. 基本的な構文
それでは、try-finallyの基本的な書き方を見てみましょう。
try
{
// ここにメインの処理を書く
Console.WriteLine("処理を実行しています。");
}
finally
{
// エラーが起きても必ず実行される処理
Console.WriteLine("後始末をしています。");
}
このコードでは、tryの中の処理を実行したあと、必ずfinallyの中の処理が実行されます。もしtryの中でエラーが発生しても、finallyの部分はスキップされずに必ず動作します。
3. 実行結果の例
先ほどのコードを実行すると、次のように表示されます。
処理を実行しています。
後始末をしています。
このように、例外がなくてもfinallyの処理が実行されます。
4. エラーが発生した場合の動作
それでは、tryの中でわざとエラーを発生させてみましょう。
try
{
Console.WriteLine("処理を開始します。");
int x = 0;
int y = 10 / x; // ここでゼロ除算エラーが発生
}
finally
{
Console.WriteLine("エラーがあっても後始末をします。");
}
実行結果は次のようになります。
処理を開始します。
エラーがあっても後始末をします。
この例ではゼロ除算エラーが発生しますが、それでもfinallyの部分は必ず実行されます。これがtry-finallyの大きな特徴です。
5. try-finallyが使われる場面
try-finallyは、次のような場面でよく使われます。
- ファイルを開いた後、必ず閉じる必要があるとき
- データベース接続を開始したら、必ず切断する必要があるとき
- メモリやリソースを確保したら、必ず解放したいとき
例えばファイルを開く場合、エラーがあっても最後にファイルを閉じなければなりません。そのような場合にtry-finallyを使うと安全です。
6. try-catchとの違い
初心者がよく混乱するのが、try-catchとtry-finallyの違いです。両方とも例外処理で使いますが、役割は異なります。
try-catchは「エラーを捕まえて処理する」ために使うtry-finallyは「エラーがあってもなくても、必ず最後に片付けをする」ために使う
つまり、catchは「エラー対応」、finallyは「後始末」と覚えると分かりやすいです。
7. 日常生活に例えて理解する
プログラミング未経験の人にも分かりやすいように、日常生活の例で考えてみましょう。例えば料理をするとき、次のような流れになります。
try部分 … 材料を切ったり炒めたりする料理の作業catch部分 … もし焦がしたら新しい材料を買いに行く対応finally部分 … 料理が成功しても失敗しても必ず台所を片付ける
このように考えると、try-finallyは「最後の片付け」を保証する役割だと理解できるでしょう。
8. try-finallyだけを使う理由
「catchを書かずにfinallyだけを使うの?」と疑問に思う人もいるでしょう。実は、エラーを捕まえて処理したいのではなく「後始末だけは必ずやりたい」という場面があるのです。
例えば、エラーは上の呼び出し元(プログラムの親側)に任せたいけれど、ここで使ったファイルや接続は必ず閉じておきたい、という状況です。その場合、try-finallyだけを書いて処理するのが適切です。
まとめ
C#の例外処理において、try-finallyという仕組みはとても素直で分かりやすい反面、その役割を深く理解すると実務でも学習でも大きな効果を発揮します。今回の記事で学んだように、try-finallyは「エラーが発生しても必ず実行したい処理」を書くための構文であり、プログラムにおける後始末を確実に行うための重要な柱になります。とくにファイル操作やデータベース接続といった外部リソースを扱う場面では、後片付けを怠るとパフォーマンスの低下や予期しない動作の原因になるため、初心者の段階から丁寧に習得しておきたい知識です。 例外処理は「エラーを無視する」「ただ止める」ためのものではなく、安全に制御を戻し、プログラム全体の安定性を保つための技術です。今回触れたtry-finallyはcatchを使わない構造のため、エラーの処理そのものは上位の呼び出し元に任せたいけれど、リソース管理だけは確実に行いたいというケースで活躍します。つまり「後始末はここで行うが、エラーの責任はこの場では引き受けない」という設計を柔軟に実現できるわけです。 また、try-finally構文はプログラムの読みやすさにも寄与します。処理の流れが自然に分かれ、どこでメイン処理が行われ、どこで後始末が実行されるかが視覚的にも明確です。実務ではコードの規模が大きくなるほど、こうした「読みやすさ」「誤解が生まれにくい構造」がとても重要になってきます。特に初心者のうちは動けば良いという考え方に偏りがちですが、動作と同じくらい大切なのが「今後も安心して動くコードを書くこと」だと言えるでしょう。 try-finallyがよく使われる例としては、ファイルのクローズ処理やネットワークストリームの解放などがあります。これらは開いたら必ず閉じなければならない仕組みになっているため、例外の有無にかかわらず最後に実行されるfinallyは非常に相性が良いのです。実際の開発現場では、リソース管理を間違えることで深刻なトラブルにつながるケースも珍しくありません。ファイルを閉じ忘れる、接続を解放し忘れる、小さなミスの積み重ねが大きな不具合になることもあります。 そのため、try-finallyという基本的な構文を深く理解しておくことは、信頼性の高いアプリケーションを作るための大きな一歩です。さらにC#ではIDisposableやusing文といった便利な仕組みも存在しますが、それらも内部的にはtry-finallyを使って実装されています。つまりtry-finallyを理解することは、C#のリソース管理の根本を理解することにつながります。 try-finallyの動きをもう一度整理すると、tryブロックでメインとなる処理が実行され、例外が投げられたかどうかに関係なくfinallyブロックが必ず実行されます。この「必ず実行される」という性質が非常に強力で、開発者が安心して処理を書ける理由にもなっています。catchを書きたくない、あるいは書くべきではない場面でも、finallyだけは常に必要な処理を保証します。
try-finallyを実際のコードで振り返る
ここでは、ファイル操作を例にtry-finallyの流れを確認できるサンプルコードを掲載します。例外処理の基本構造や後始末の流れを目で追いながら理解できるよう、できるだけ素直な形にまとめています。
public void ReadTextFile(string path)
{
StreamReader reader = null;
try
{
reader = new StreamReader(path);
string text = reader.ReadToEnd();
Console.WriteLine("読み込んだ内容:");
Console.WriteLine(text);
}
finally
{
if (reader != null)
{
Console.WriteLine("ファイルを閉じています...");
reader.Close();
}
}
}
このコードでは、メイン処理と後始末の役割が明確に分かれています。例外が発生しても、reader.Close()が確実に実行され、リソースが安全に解放されます。try-finallyは単純な構文ですが、実際のアプリケーションでは非常に重要な役割を果たしていることが分かるはずです。
生徒
「try-finallyって難しいと思っていましたけど、意外とシンプルなんですね。後始末が必ず実行される仕組みだと分かって安心しました。」
先生
「そうなんです。シンプルだけれど大切な場面が多い構文なんですよ。特に失敗しても成功しても必ず終わらせる必要がある処理とは相性が抜群です。」
生徒
「catchを書かずにfinallyだけ使う理由もよく分かりました。エラー処理は上のメソッドに任せつつ、後始末は自分で責任を持つって感じですね。」
先生
「その理解はとても正しいです。プログラムは分担と責任の線引きが大切ですからね。今回の学びは必ず実務にも役立ちますよ。」
生徒
「これからファイル処理とか接続処理を書くときに意識して使っていきます!理解が深まって自信がつきました!」