ここまで、オブジェクト指向までひととおり学びました。

ここからは、入門の次のステップ。実用的な機能に入っていきます。まずは、エラーとうまく付き合う例外処理(れいがいしょり)です。

例外処理とは、エラーが起きても、プログラムを止めずに対応する仕組みです。

エラーが起きると、プログラムは止まる

これまでも、何度か「エラー」が出てきました。実は、プログラムはエラーが起きると、その場で止まってしまいます

たとえば、第5回でやった「入力を数字に変換する」コード。

Console.WriteLine("年齢を入力してください");
int age = int.Parse(Console.ReadLine());
Console.WriteLine("あなたは" + age + "歳ですね");

ここで、ユーザーが「20」ではなく「あいうえお」と入力したら、どうなるでしょう。

int.Parse は「あいうえお」を数字に変換できません。エラーが起きて、プログラムはそこで止まります。「あなたは…歳ですね」は、表示されません。

ユーザーの入力ミスひとつで、プログラム全体が止まる。これは困りますよね。

try-catch ── エラーを受け止める

そこで使うのが、try(トライ)と catch(キャッチ)です。

try
{
    Console.WriteLine("年齢を入力してください");
    int age = int.Parse(Console.ReadLine());
    Console.WriteLine("あなたは" + age + "歳ですね");
}
catch
{
    Console.WriteLine("数字を入力してください");
}

「あいうえお」と入力すると、こうなります。

年齢を入力してください
あいうえお
数字を入力してください

エラーで止まらず、「数字を入力してください」と表示して、続きました。

形を見てみましょう。

  • try { } … 「エラーが起きるかもしれない処理」を、この中に書く
  • catch { } … 「もしエラーが起きたら」、この中の処理をする

野球の「キャッチ」と同じイメージです。try の中で飛んできたエラー(ボール)を、catch が受け止める。受け止めるから、プログラムは倒れずに済むんです。

エラーの中身を見る

catch では、起きたエラーの情報を受け取れます。

try
{
    int age = int.Parse("あいうえお");
}
catch (Exception ex)
{
    Console.WriteLine("エラーが起きました:" + ex.Message);
}

Exception ex で、エラーの情報を ex という箱に受け取ります。ex.Message には、エラーの内容(何が問題だったか)が入っています。

開発中は、この ex.Message を表示すると、「何が原因でエラーになったか」が分かって便利です。

Exception は「例外」という意味。C#では、エラーのことを「例外」と呼びます。だから「例外処理」なんですね。)

finally ── 最後に必ずやること

もうひとつ、finally(ファイナリー)という仲間がいます。エラーが起きても起きなくても、最後に必ず実行される処理です。

try
{
    // ファイルを開いて、何か処理する
}
catch (Exception ex)
{
    Console.WriteLine("エラー:" + ex.Message);
}
finally
{
    Console.WriteLine("処理を終了します");   // 必ず実行される
}

成功しても、エラーが起きても、finally の中は必ず通ります。「後片付け」によく使われます。たとえば「開いたファイルを閉じる」など、何があっても必ずやりたいことを書きます。

どこに使うべきか ── 現場の感覚

ここは少し、現場の話を。

例外処理は便利ですが、何でもかんでも try-catch で囲むのは、よくありません

囲むべきなのは、「自分では防ぎきれないエラー」が起きるところです。

  • ユーザーの入力(何を入れるか分からない)
  • ファイルの読み書き(ファイルが無いかもしれない)
  • ネットワーク通信(つながらないかもしれない)

逆に、自分のコードのミス(バグ)は、try-catch で隠すのではなく、直すべきです。エラーを catch で握りつぶすと、バグに気づけなくなります。

外の世界とやりとりするところに、例外処理」。この感覚を持っておくと、使いどころを間違えません。

つまずきポイント

初心者がやりがちなのが、catch で何もしないことです。

try
{
    // 処理
}
catch
{
    // 何も書かない ← エラーを握りつぶしている!
}

これだと、エラーが起きても何も起きなかったように見えてしまいます。原因が分からず、後で困ります。

最低でも、「何が起きたか」を表示するか、記録する。エラーは「受け止めて、適切に対応する」もの。「受け止めて、捨てる」では、意味がありません。

まとめ

例外処理は、エラーが起きても止まらないようにする仕組み。

try
{
    // エラーが起きるかもしれない処理
}
catch (Exception ex)
{
    // エラーが起きたときの対応
}
finally
{
    // 必ず実行される後片付け
}
  • try でエラーを受け止め、catch で対応する
  • 「外の世界とのやりとり」に使う(入力・ファイル・通信)
  • catch で握りつぶさず、必ず何か対応する

次回は、C#で最も多いエラーの元、null と null許容型 です。