|
|
例外処理の重要性 |
|
例外とは、想定外の値が代入されたときや、ファイルのオープンが正常に行われなかったときに起きてしまうエラーの事を言います。例えば以下のプログラムを実行し、コンソールから要求される値に数値以外の文字列を入力してみてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("数値を入力してください:");
int i = int.Parse(Console.ReadLine());
Console.ReadLine();
}
}
} |
実行結果(要求された値にはiと入力)
このプログラム、どこに問題があるかわかりますか?「int.Parse」メソッドは文字列を数値に変換するためのメソッドです。その引数は必ず数字でなければならないにもかかわらず、コンソール画面からは文字列を渡してしまった為、このような例外が発生してしまいました。
プログラミングは例外との戦いでもあります。実際、プログラミングしているうちの半分ではどのような例外にも耐えうる強固なプログラムに仕上げることです。
このような例外に対処する機能の実装を例外処理と呼び、C#では例外処理用の便利なステートメントが用意されています。この章では、例外処理に対処するための各種ステートメントの紹介と、その実装方法を解説します。
|
|
try-catchステートメントを使用した例外処理 |
|
try-catchステートメントでは、例外が発生する可能性があるコードを「try」で囲み、実際に例外が発生した場合の処理を「catch」ステートメントで囲みます。
1
2
3
4
5
6
7
8
9
|
try
{
//例外が発生する可能性があるコードを囲む
}
catch
{
//実際に例外が発生したときの処理を記述する
} |
では、先程のプログラムを例外が発生しないようにコーティングし直してみましょう。以下に改良したコードを示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("数値を入力してください:");
try
{
int i = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("不正な数値が入力されました");
}
Console.ReadLine();
}
}
} |
実行結果(要求された値にはiと入力)
1
2
|
数値を入力してください:i
不正な数値が入力されました |
今回のプログラムでは、例外を発生させる可能性のある15行目のコードを「try」で囲んでいます。もし例外が発生した場合は「catch」で囲んだコードを実行し、入力された値が不正なものであることを利用者に知らせ、処理を続行させます。
しかし、この例外処理は利用者にとってあまり優しいものとは言えません。なぜならば、今入力された値のどこが問題であったかを、具体的に示していないからです。ここで「不正な数値が入力されました」のところを「指定できるのは数字のみです」としても良いのですが、このコードでは嘘になる可能性があります。例えば、もう一度このプログラムを実行して15桁ぐらいの長い数字を入力し、実行してください。
実行結果(要求された値には111111111111111と入力)
1
2 |
数値を入力してください:111111111111111
不正な数値が入力されました |
プログラムは続行できていますが、またしても例外が発生しているようです。int型で取り扱える数値の範囲は-2,147,483,648から2,147,483,647の間の整数のみでした。今回の例外は、int型に格納できる範囲を超えた値を代入しようとしたため、例外が発生してしまったのです。
|
|
特定の例外のみをcatchさせる |
|
では、発生した例外の種類に応じて例外処理の種類を変えることはできるのでしょうか?実は、「catch」は複数することができ、また例外の種類をパラメータとして与えることができます。
1
2
3
4
|
catch(例外の種類)
{
//実際に例外が発生したときの処理を記述する
} |
以下のプログラムは、例外の種類によって異なるメッセージを通知するプログラム例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("数値を入力してください:");
try
{
int i = int.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("数字以外の値が入力されています");
}
catch (OverflowException)
{
Console.WriteLine("範囲外の値が入力されました");
}
catch
{
Console.WriteLine("不正な値が入力されました");
}
Console.ReadLine();
}
}
} |
実行結果
1
2
3
4
5
6
7
|
//要求された値にiと入力した場合
数値を入力してください:i
数字以外の値が入力されています
//要求された値に111111111111111と入力した場合
数値を入力してください:111111111111111
範囲外の値が入力されました |
今回の例では、ひとつの「try」に対して複数の「catch」が指定されています。「catch」の横の括弧の中に書かれているのが例外の種類です。25行目では、万が一指定した例外以外の例外が発生したときのために何も指定されていない「try」も実装しています。「FormatException」は引数の書式が仕様に一致していない場合に、「OverflowException」は範囲外の値が代入されようとしたときに発生する例外です。なお、例外の種類と内容は例外が発生したときに表示されるダイアログに書かれています。また、例外の種類に関してはMSDNのホームページに例外に関するドキュメントが公開されていますので、こちらもご参照ください。
MSDN:例外処理アシスタント
http://msdn.microsoft.com/ja-jp/library/197c1fsc.aspx |