このクラスは、すべての例外の基本クラスです。エラーが発生すると、システムまたは現在実行中のアプリケーションは、そのエラーに関する情報が格納された例外をスローすることによりエラーをレポートします。スローされた例外は、アプリケーションまたは既定の例外ハンドラによって処理されます。
共通言語ランタイムは、オブジェクトとして例外の表現に基づく例外処理モデルを提供し、また、プログラム コードと例外処理コードをそれぞれ try ブロックと catch ブロックに分離します。catch ブロックは 1 つ以上あり、それぞれのブロックは、特定の型の例外を処理するように設計されていることも、一方のブロックが他方のブロックよりも具体的な例外を受け取るように設計されていることもあります。
アプリケーションが、あるブロックのアプリケーション コードの実行中に発生する例外を処理する場合は、そのコードを try ステートメントの内部に入れる必要があります。try ステートメント内のアプリケーション コードは、try ブロックです。try ブロックによりスローされた例外を処理するアプリケーション コードは catch ステートメントの内部に入れられ、catch ブロックと呼ばれます。0 個以上の catch ブロックが try ブロックに関連付けられ、それぞれの catch ブロックには、そのブロックが処理する例外の種類を判断する型フィルタが含まれています。
try ブロックで例外が発生すると、その例外を処理する catch ブロックが見つかるまで、関連付けられている catch ブロックが、アプリケーション コード内での出現順に検索されます。catch ブロックの型フィルタが T または T の派生元の型を指定している場合、その catch ブロックは T 型の例外を処理します。例外を処理する最初の catch ブロックが見つかると、システムは検索を中断します。そのため、アプリケーション コードでは、このセクション以降の例で示されるように、ある種類を処理する catch ブロックは、その基本となる種類を処理する catch ブロックよりも前に指定される必要があります。System.Exception を処理する catch ブロックは最後に指定されます。
現在の try ブロックに関連付けられた catch ブロックでは例外を処理するブロックが見つからず、現在の呼び出しにおいて現在の try ブロックが他の try ブロックの入れ子になっている場合は、その外側の try ブロックに関連付けられた catch ブロックが検索されます。例外を処理する catch ブロックが見つからない場合は、現在の呼び出しにおける入れ子レベルの外側をさかのぼって検索が行われます。現在の呼び出しの中で例外を処理する catch ブロックが見つからない場合、その例外はコール スタックに渡され、上位レベルのスタック フレームで、その例外を処理する catch ブロックが検索されます。コール スタックの検索は、その例外が処理されるか、そのコール スタックにフレームがなくなるまで続けられます。例外を処理する catch ブロックが見つからずにコール スタックの最上位レベルに達した場合は、既定の例外ハンドラがその例外を処理し、アプリケーションが終了します。
例外の種類は、次の機能をサポートしています。
-
ユーザーが判読できる、エラーを説明したテキスト。例外が発生すると、ランタイムはテキスト メッセージを提供して、ユーザーにエラーの性質を通知したり、問題を解決する処置のヒントを与えます。このテキスト メッセージは、例外オブジェクトの Message プロパティに保持されます。例外オブジェクトの作成時に、その特定の例外の詳細を説明するテキスト文字列をコンストラクタに渡すことができます。コンストラクタに渡すエラー メッセージの引数を指定しない場合は、既定のエラー メッセージが使用されます。
-
例外がスローされたときのコール スタックの状態。StackTrace プロパティには、コード内のエラー発生箇所を判断するために使用できるスタック トレースが保持されています。スタック トレースは、呼び出されたすべてのメソッドと、呼び出しを行うソース ファイル内の行番号の一覧を表示します。
Exception 基本クラスには例外の 2 つのカテゴリがあります。
Exception には、例外のコード位置、種類、ヘルプ ファイル、および理由を識別するのに役立つ多くのプロパティが含まれています。それらのプロパティには、StackTrace、InnerException、Message、HelpLink、HResult、Source、TargetSite、および Data があります。
2 つ以上の例外の間に因果関係があると、InnerException プロパティにはこの情報が保持されます。外部例外は、この内部例外に応答してスローされます。外部例外を処理するコードは、先に発生した内部例外からの情報を使用して、より的確にエラーを処理できます。例外に関する補足情報は、Data プロパティに格納できます。
例外オブジェクトの作成中にコンストラクタに渡されたエラー メッセージ文字列はローカライズされているため、ResourceManager を使用してリソース ファイルから指定できます。ローカライズされたリソースの詳細については、System.Resources 名前空間の概要のトピックおよび「リソースのパッケージ化と配置」を参照してください。
例外の発生理由に関する詳細情報をユーザーに提供するために、HelpLink プロパティにヘルプ ファイルの URL (または URN) を保持させることができます。
Exception は、値 0x80131500 を保持する HRESULT COR_E_EXCEPTION を使用します。
Exception のインスタンスの初期プロパティ値の一覧については、Exception コンストラクタのトピックを参照してください。
パフォーマンスに関する注意事項
例外をスローしたり処理したりするときには、大量のシステム リソースおよび実行時間が使われます。予測可能なイベントやフロー制御の処理のためではなく、真に異常な状態の場合のみ例外をスローしてください。たとえば、アプリケーションでは有効なパラメータでメソッドが呼び出されることを前提としているので、メソッド引数が無効な場合は適切な理由で例外をスローできます。メソッド引数が無効であるということは、何か異常が発生していることを示しています。これに対して、ユーザー入力が無効である場合は例外をスローしないでください。ユーザーが無効なデータを入力する場合があることは予測可能な事態だからです。このような場合は、ユーザーに有効な入力を実行する機会を与える再試行メカニズムを提供します。
異常な状況に対して例外をスローする場合は、特定の例外に適用されるハンドラではなく、アプリケーションの大半に適用される汎用目的の例外ハンドラで例外をキャッチします。この手法は、エラーの大半は発生位置の周辺で検証やエラー処理コードを使って対応できるものであり、例外のスローまたはキャッチは不要であるという考え方に基づいています。汎用目的の例外ハンドラがキャッチする対象は、アプリケーションの任意の場所でスローされ、適切に予測できない例外です。
また、リターン コードが十分である場合に例外をスローしたり、リターン コードを例外に変換したりしないでください。例外をキャッチした場合に、それを無視して処理を続行することは避けてください。