C#の例外処理 - シンプルな例外のキャッチ (try ~ catch文の利用) - C#

C# での例外処理での例外のキャッチ(例外の検出)を紹介します。

例外のキャッチが無い場合

最初に例外処理(例外のキャッチ)が無い場合の動作を確認します。

UI

下図のUIを作成します。フォームにTextBoxを2つ、ButtonとLabelを一つづつ配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CatchException
{
  public partial class FormCatchException : Form
  {
    public FormCatchException()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      int a = Convert.ToInt32(textBox1.Text);
      int b = Convert.ToInt32(textBox2.Text);
      int c = a + b;
      label1.Text = Convert.ToString(c);
    }
  }
}

コードの解説

ボタンのクリックイベントが実装されており、ボタンをクリックすると、テキストボックスに入力された値を数値に変換し、変数a,bに格納します。その後、変数aとbの和を変数cに代入し、変数cの値をLabelに表示します。
    private void button1_Click(object sender, EventArgs e)
    {
      int a = Convert.ToInt32(textBox1.Text);
      int b = Convert.ToInt32(textBox2.Text);
      int c = a + b;
      label1.Text = Convert.ToString(c);
    }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


テキストボックスに数値を入力します。今回は"12"と"6"を入力します。入力後[button1]をクリックします。


入力した数値の和の値"18"がLabelに表示されました。問題なく動作しています。


続いて、片方のテキストボックスに文字列を入力します。今回は"ぺんぎん"の文字列を入力します。数値ではない値のため、変換で失敗することは確実です。入力後[button1]ボタンをクリックします。


Visual Studioがデバッグモードであれば、コードウィンドウが開き、実行に失敗し例外が発生した場所が表示されます。今回はtextBox1の価が数値ではない文字列であったため、Convert.ToInt32()メソッドの入力パラメーターの形式に問題が起き、System.FormatException の例外が発生しています。


継続して実行すると、アプリが待機状態のままとなるか、または、アプリが強制終了します。

例外のキャッチ処理の記述

先の例では例外が発生しアプリケーションが停止しましたが、発生した例外を処理する(キャッチする)ことで、アプリケーションが停止せずに動作させることができます。

書式

例外をキャッチするには、例外をキャッチするコードをtryブロックで囲み、catch で例外時の処理を記述します。
try{
  (...例外処理をするコード)
}
catch(例外の型名)
{
  (...例外が発生したときに処理されるコード)
}

try{
  (...例外処理をするコード)
}
catch(例外の型名 例外のオブジェクト変数)
{
  (...例外が発生したときに処理されるコード)
}

下記の書式も可能ですが、すべての例外がキャッチされてしまうため、あまりお勧めできません。
try{
  (...例外処理をするコード)
}
catch
{
  (...例外が発生したときに処理されるコード)
}

補足

例外処理のブロック処理後に必ず実行させるコードがある場合は finally ブロックを利用します。finally内に記述されたコードは、tryブロックのコードが正常に実行された場合でも、例外が発生してcatchブロック内が実行された場合でも、実行後に必ずfinallyブロックのコードが実行されます。
try{
  (...例外処理をするコード)
}
catch(例外の型名)
{
  (...例外が発生したときに処理されるコード)
}
finally{
  (...tryのブロックの実行後に必ず処理をするコード)
}

try{
  (...例外処理をするコード)
}
catch(例外の型名 例外のオブジェクト変数)
{
  (...例外が発生したときに処理されるコード)
}
finally{
  (...tryのブロックの実行後に必ず処理をするコード)
}

コード

先のプログラムのコードを下記コードに変更します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CatchException
{
  public partial class FormCatchException : Form
  {
    public FormCatchException()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      try {
        int a = Convert.ToInt32(textBox1.Text);
        int b = Convert.ToInt32(textBox2.Text);
        int c = a + b;
        label1.Text = Convert.ToString(c);
      }
      catch (FormatException exception) {
        label1.Text = "形式が不正";
      }
    }
  }
}

解説

try ブロック内のコードが例外をキャッチできるコードになります。今回はテキストボックスに入力された値が数値でない場合の例外をキャプチャーするため、例外の方は FormatException を指定しています。テキストボックスの入力文字列が数値でない場合には変換に失敗し、FormatException例外が発生し、catch ブロック内のコードが実行されます。catchブロックでの処理により labelに "形式が不正" の文字を表示します。
    private void button1_Click(object sender, EventArgs e)
    {
      try {
        int a = Convert.ToInt32(textBox1.Text);
        int b = Convert.ToInt32(textBox2.Text);
        int c = a + b;
        label1.Text = Convert.ToString(c);
      }
      catch (FormatException exception) {
        label1.Text = "形式が不正";
      }
    }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


1つ目のテキストボックスに"ぺんぎん"、2つ目のテキストボックスに"12"を入力します。入力後[button1]をクリックします。


1つ目のテキストボックスの値が数値ではないため Convert.ToInt32 で例外が発生しcatchのブロック内のコードが実行され、Labelに"形式が不正"の文字が表示されます。


なお、両方のテキストボックスに数値が入力されていた場合に[button1]をクリックすると、Labelには2つの数値の和が表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2017-12-20
作成日: 2017-06-26
iPentec all rights reserverd.