例外 (C# と Java の比較)
更新 : 2007 年 11 月
例外処理は、C# と Java では基本的に同じです。
プログラムの実行中にエラーが発生すると、.NET Framework 共通言語ランタイム (CLR) は、エラー情報を示す Exception オブジェクトを作成します。.NET Framework では、Exception がすべての例外クラスの基本クラスです。Exception クラスから派生する例外には、SystemException と ApplicationException の 2 つのカテゴリがあります。System 名前空間のすべての種類は SystemException から派生するのに対し、ユーザー定義の例外は、ランタイム エラーとアプリケーション エラーを区別するために ApplicationException から派生する必要があります。一般的な System 例外は次のとおりです。
IndexOutOfRangeException : 配列またはコレクションのサイズを超えるインデックスが使用されている。
NullReferenceException : 参照に有効なインスタンスが設定される前に、その参照のプロパティまたはメソッドが使用されている。
ArithmeticException : 操作の結果、オーバーフローまたはアンダーフローが発生した。
FormatException : 引数またはオペランドの書式に誤りがある。
Java の場合と同様に、コードで例外が発生する可能性がある場合は、そのコードを try ブロック内に配置します。直後の 1 つ以上の catch ブロックでエラー処理を実行しますが、例外がスローされてもされなくても実行するすべてのコードに finally ブロックを適用することもできます。詳細については、「try-catch (C# リファレンス)」および「try-catch-finally (C# リファレンス)」を参照してください。
複数の catch ブロックを使用したときは、スローされた例外に一致する最初の catch ブロックだけが実行されるので、キャッチされた例外を、一般性が低い方から高くなる順に配置する必要があります。C# コンパイラは、これを強制しますが、Java コンパイラは強制しません。
また、C# では、Java と違って catch ブロックの引数は必須ではありません。引数が存在しない場合、catch ブロックはすべての Exception クラスに適用されます。
たとえば、ファイルからの読み取り時には、FileNotFoundException や IOException が発生することがあるので、次のコードに示すように、より限定された FileNotFoundException ハンドラを最初に配置するのが適切です。
try
{
// code to open and read a file
}
catch (System.IO.FileNotFoundException e)
{
// handle the file not found exception first
}
catch (System.IO.IOException e)
{
// handle any other IO exceptions second
}
catch
{
// a catch block without a parameter
// handle all other exceptions last
}
finally
{
// this is executed whether or not an exception occurs
// use to release any external resources
}
Exception の派生クラスを、独自の例外クラスとして作成できます。たとえば、次のコードは、新しい Employee に設定された部署が無効な場合などにスローできる InvalidDepartmentException クラスを作成します。このコードでは、ユーザー定義例外のクラス コンストラクタが base キーワードを使用して基本クラス コンストラクタを呼び出し、適切なメッセージを送ります。
public class InvalidDepartmentException : System.Exception
{
public InvalidDepartmentException(string department) : base("Invalid Department: " + department)
{
}
}
続いて、次のようなコードを使用して例外をスローできます。
class Employee
{
private string department;
public Employee(string department)
{
if (department == "Sales" || department == "Marketing")
{
this.department = department;
}
else
{
throw new InvalidDepartmentException(department);
}
}
}
C# では、チェックされた例外をサポートしません。Java では、チェックされた例外を throws キーワードで宣言し、呼び出し側のコードで処理する必要がある特定の種類の例外をメソッドがスローできるようにします。