連載

C#入門

第18回 例外とエラー処理

(株)ピーデー
川俣 晶
2001/12/22


例外処理の再発生

 ただ単に例外をキャッチして処理を行うだけでは不十分な場合がある。例えば、1つの例外について、別々の階層のメソッド内の別々のcatch文の双方でエラー処理を行う必要が生じる場合がある。このような場合、catchブロック内でさらにもう一度例外を発生させる必要が出てくる。このように同じ例外を再度発生させるというケースでは、専用の構文が使用できる。以下はそれを使用したサンプル・ソースである。

 1: using System;
 2: using System.IO;
 3: using System.Text;
 4:
 5: namespace ConsoleApplication43
 6: {
 7:   class DelayedFileReader
 8:   {
 9:     private string _fileName;
10:     public DelayedFileReader( string fileName )
11:     {
12:       _fileName = fileName;
13:       if( !File.Exists( fileName ) )
14:       {
15:         throw new FileNotFoundException( "ファイルが見つかりません。", fileName );
16:       }
17:     }
18:   }
19:   class Class1
20:   {
21:     private static void sample()
22:     {
23:       try
24:       {
25:         DelayedFileReader reader = new DelayedFileReader("存在しない.txt");
26:       }
27:       catch( FileNotFoundException e )
28:       {
29:         Console.WriteLine( "Class1.sampleでFileNotFoundException例外を確認しました。" );
30:         throw;
31:       }
32:     }
33:     static void Main(string[] args)
34:     {
35:       try
36:       {
37:         sample();
38:       }
39:       catch( FileNotFoundException e )
40:       {
41:         Console.WriteLine( "Class1.MainでFileNotFoundException例外を確認しました。" );
42:       }
43:     }
44:   }
45: }
例外を再発生させるサンプル・プログラム12
一度キャッチした例外を再度スローし、上位メソッドがもう一度例外をキャッチできるチャンスを発生させている。

 これを実行すると以下のようになる。

サンプル・プログラム12の実行結果
Class1.sampleメソッドで例外がキャッチし、さらにそのメソッドを呼び出していたMainメソッドでも例外をキャッチしていることが分かる。

 このサンプル・ソースでは、15行目で発生する例外を27行目からのcatchブロックでキャッチしているが、ここでキャッチしなければ、39行目からのcatchブロックでもキャッチされるはずのものである。両方でエラー処理を行いたい場合は、27行目からのcatchブロック内でもう一度同じ例外を発生させ、39行目からのcatchブロックに実行するチャンスを与える必要がある。そのために、例外を再発生させているのが30行目のthrow文だが、見てのとおり、同じ例外を再発生させる場合は、例外インスタンスを指定する必要はない。

例外クラスを自作する 

 例外で使用するクラスは、Exceptionクラスを継承していればよい。つまり、自分でExceptionクラスを継承したクラスを作れば、それも利用できる。実際に記述してみた例は以下のとおりだ。

 1: using System;
 2: using System.IO;
 3: using System.Text;
 4:
 5: namespace ConsoleApplication44
 6: {
 7:   class MyException : Exception
 8:   {
 9:     public MyException( string message ) : base( message )
10:     {
11:     }
12:   }
13:   class Class1
14:   {
15:     static void Main(string[] args)
16:     {
17:       throw new MyException("自作例外");
18:     }
19:   }
20: }
例外クラスを自作したサンプル・プログラム13
Exceptionクラスを継承したクラスを定義している。

 これを実行すると以下のようになる。

サンプル・プログラム13の実行結果
プログラムで定義した例外“MyException”が発生しているのが分かる。

 画面写真を見て分かるとおり、MyExceptionはシステムから例外の一種として認知されており、問題なくコンソールに情報が出力されている。Exceptionクラスには3つのコンストラクタがあるが、よく使われるのは文字列の引数が1個のものである。これは8行目のように、引数をちゃんと親クラスに渡してやらないとエラーになってしまうので、そのように記述する必要がある。それ以外は、プログラマが必要だと思う機能をこのクラスに書き加えてよい。

 このような自作例外クラスを用意すると、自作プログラム内のエラー処理を円滑に行える場合もあるので、覚えておくとよいだろう。たとえ、自作例外クラス内に機能らしい機能が必要とされていないとしても、例外を区別できるというだけでメリットがある場合も多い。


 INDEX
  第18回 例外とエラー処理
    1.例外とは何か?
    2.例外を区別して扱う
    3.確実な終了処理を行うfinally
    4.深い階層からの例外
  5.例外処理の再発生
    6.例外クラスのインスタンスを活用する
 
「C#入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間