連載

プロフェッショナルVB.NETプログラミング

第14回 エラーと例外処理

(株)ピーデー
川俣 晶
2002/08/24

Page1 Page2 Page3

構造化例外処理と非構造化例外処理の混用

 構造化例外処理と非構造化例外処理の機能は同時に使うことができるだろうか? 例えば、上記のサンプル・ソースでエラーの種類を判定するために、Errオブジェクトが使えるだろうか? 以下はそれを確認するために記述したサンプル・ソースである。

  1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  2:   Dim i As Integer
  3:   For i = -2 To 2
  4:     Dim j As Integer
  5:     Try
  6:       j = 10 \ i
  7:     Catch ex As Exception
  8:       If Err.Number = 11 Then
  9:         Trace.WriteLine("∞")
 10:       Else
 11:         Throw
 12:       End If
 13:     End Try
 14:     Trace.WriteLine(j)
 15:   Next
 16: End Sub
構造化例外処理と非構造化例外処理の機能を同時に使用したサンプル・プログラム5

 これを実行すると以下のようになる。ただしシステムからのメッセージは除いてある。

 1: -5
 2: -10
 3:
 4: -10
 5: 10
 6: 5
サンプル・プログラム5の実行結果

 見てのとおり、構造化例外処理の中で、非構造化例外処理用のErrオブジェクトを使用してエラー番号を調べているが、確かに判定が実行されている。つまり例外クラスの名前ではなく、エラー番号によるエラーの種類の判定が実現できている。

 しかし、このような方法はあまりお勧めではない。現在はたまたま動いているが、VB.NETの将来バージョンで動作するか分からないし、そもそも、将来的に非構造化例外処理がサポートされなくなる可能性も、決して小さくはない。できるだけ、構造化例外処理だけで記述するように心掛ける方が安心だろう。

On Error Resume Next

 VB 6には、On Error Resume Next文がある。これは、エラーが発生してもそのまま次のステートメントに動作を進めるというラフな機能を指定する。当然、そのままではエラーが起きてもデタラメな動作が続くだけの無意味なプログラムになってしまう。では、On Error Resume Next文の存在意義は何かというと、エラーが発生する可能性のあるステートメントの実行直後に、Errオブジェクトを参照して、エラーの有無を確認するようなプログラミング・スタイルを実現することである。実際にVB 6で、このようなスタイルで記述したソースを以下に示す。

  1: Private Sub Form_Load()
  2:   On Error Resume Next
  3:   Dim i As Integer
  4:   For i = -2 To 2
  5:     Dim j As Integer
  6:     j = 10 / i
  7:     If Err = 11 Then
  8:       Debug.Print "∞"
  9:       Err.Clear
 10:     End If
 11:     Debug.Print j
 12:   Next
 13: End Sub
On Error Resume Next文を使用したVB 6のサンプル・プログラム6

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

 1: -5
 2: -10
 3:
 4: -10
 5:  10
 6:  5
サンプル・プログラム6の実行結果

 見てのとおり、On Error Gotoを使用する場合より処理が直線的になって、流れを追いやすい。しかし、プログラマーがあらかじめ想定していないエラーが発生した場合、そのまま処理が続く危険もある。

 さて、このソースをできるだけ忠実にVB.NET上に再現したのが下記のソースである。

  1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  2:   On Error Resume Next
  3:   Dim i As Integer
  4:   For i = -2 To 2
  5:     Dim j As Integer
  6:     j = 10 \ i
  7:     If Err.Number = 11 Then
  8:       Trace.WriteLine("∞")
  9:       Err.Clear()
 10:     End If
 11:     Trace.WriteLine(j)
 12:   Next
 13: End Sub
サンプル・プログラム6をVB.NETで再現したサンプル・プログラム7

 これを実行すると以下のようになる。ただしシステムからのメッセージは除いてある。

 1: -5
 2: -10
 3:
 4: -10
 5: 10
 6: 5
サンプル・プログラム7の実行結果

 見てのとおり、ほとんど変わらないソース・コードが使用できることが分かるだろう。しかし、On Error Resume Next文は、非構造化例外処理の機能の1つである。構造化例外処理を使うと、どのように記述すればそれに相当するソース・コードが作成できるだろうか。

 結論をいえば、On Error Resume Next文に相当する機能は、構造化例外処理には含まれていない。これは、すべてのエラー処理を暗黙のうちに決め打ちしてしまうことが危険だから、と解釈すべきだろう。起こり得るエラーに対する対応コードはすべて明示的にTry文とCatch文で表現することは、プログラムの品質を向上させるうえで意味があることである。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第14回 エラーと例外処理
    1.On Error Gotoを使う
  2.構造化例外処理と非構造化例外処理の混用
    3.複数のエラーを扱う
 
「プロフェッショナルVB.NETプログラミング」


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 記事ランキング

本日 月間