マネージド コードのアサーション

アサーション、つまり Assert ステートメントは、条件をテストします。この条件は、Assert ステートメントへの引数として指定します。 条件が true と評価された場合、アクションは発生しません。 条件が false と評価された場合、アサーションは失敗です。 デバッグ ビルドで実行している場合、プログラムは中断モードになります。

このトピックの内容

System.Diagnostics 名前空間内の Assert

Debug.Assert メソッド

Debug.Assert の副作用

Trace および Debug の必要条件

Assert の引数

Assert の動作のカスタマイズ

構成ファイルでのアサーションの設定

System.Diagnostics 名前空間内の Assert

Visual Basic および Visual C# では、Assert 名前空間内の Debug または Trace から System.Diagnostics メソッドを使用できます。 Debug クラスのメソッドはプログラムのリリース バージョンには含まれないので、リリース コードのサイズを増加させたり処理速度を低下させることはありません。

C++ は、Debug クラスのメソッドをサポートしていません。 ただし、Trace クラスを使って条件付きコンパイル (#ifdef DEBUG... #endif など) を行うことで、同じ効果が得られます。

このトピックの内容

Debug.Assert メソッド

System.Diagnostics.Debug.Assert メソッドを自由に使用して、コードが正しい場合に true になる条件をテストできます。 たとえば、整数の除算関数を記述したとします。 数学の規則により、0 での除算は不可能です。 これはアサーションを使ってテストできます。

int IntegerDivide ( int dividend , int divisor )
{
    Debug.Assert ( divisor != 0 );
    return ( dividend / divisor );
}

デバッガーでこのコードを実行すると、アサーション ステートメントが評価されますが、リリース バージョンでは比較は行われません。このため、追加のオーバーヘッドは発生しません。

別の例を示します。 次のような、当座預金口座を実装するクラスがあります。

float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

口座から現金を引き出す前に、これから引き出す額に対して残高が十分かどうかを確認します。 残高照会のためのアサーションは次のように記述できます。

float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

コードのリリース バージョンを作成すると、System.Diagnostics.Debug.Assert メソッドの呼び出しは無効になります。 つまり、残高照会は、リリース バージョンには反映されません。 この問題を解決するには、System.Diagnostics.Debug.AssertSystem.Diagnostics.Trace.Assert で置き換えます。Trace.Assert は、リリース バージョンで無効になりません。

System.Diagnostics.Trace.Assert の呼び出しを使用すると、System.Diagnostics.Debug.Assert の呼び出しとは異なり、リリース バージョンに対してオーバーヘッドがかかります。

このトピックの内容

Debug.Assert の副作用

System.Diagnostics.Debug.Assert を使用する場合は、Assert が削除される場合、Assert 内のコードによってプログラムの結果が変化しないことを確認します。 そうしないと、プログラムのリリース バージョンにのみ現れるバグを誤って導入する可能性があります。 関数やプロシージャの呼び出しを含むアサートについては、特に注意が必要です。

// unsafe code
Debug.Assert (meas(i) != 0 );

System.Diagnostics.Debug.Assert をこのように使用するのは一見安全に思われますが、meas 関数は呼び出されるたびにカウンターを更新します。 リリース バージョンをビルドすると、この meas の呼び出しは除去されるので、カウンターは更新されません。 これが、副作用を伴う関数の例です。 副作用のある関数呼び出しを除去すると、リリース バージョンにだけ現れるバグが発生する可能性があります。 このような問題を防ぐため、System.Diagnostics.Debug.Assert ステートメントには関数呼び出しを配置しないでください。 関数の代わりに、次のように一時変数を使用します。

temp = meas( i );
Debug.Assert ( temp != 0 );

System.Diagnostics.Trace.Assert を使用する場合でも、Assert ステートメント内に関数呼び出しを配置しないようにします。 System.Diagnostics.Trace.Assert ステートメントはリリース ビルドで除去されないため、関数呼び出しは安全です。 しかし、そのような構造体を避ける習慣を付けておくことで、System.Diagnostics.Debug.Assert を使用する際に間違いを犯す可能性が低くなります。

このトピックの内容

Trace および Debug の必要条件

Visual Studio ウィザードを使用してプロジェクトを作成すると、リリースとデバッグの両方の構成に TRACE シンボルが既定で定義されます。 DEBUG シンボルは、既定ではデバッグ ビルドにだけ定義されます。

それ以外の場合は、Trace メソッドが動作するように、プログラムのソース ファイルの先頭に次のいずれかを記述する必要があります。

  • #Const TRACE = True (Visual Basic の場合)

  • #define TRACE (Visual C# および C++ の場合)

    または、次に示すように、TRACE オプションを使用してプログラムをビルドする必要があります。

  • /d:TRACE=True (Visual Basic の場合)

  • /d:TRACE (Visual C# および C++ の場合)

    C# または Visual Basic のリリース ビルドで Debug メソッドを使用する必要がある場合は、リリース構成にデバッグ シンボルを定義する必要があります。

    C++ は、Debug クラスのメソッドをサポートしていません。 ただし、Trace クラスを使って条件付きコンパイル (#ifdef DEBUG... #endif など) を行うことで、同じ効果が得られます。 これらのシンボルは [<プロジェクト> プロパティ ページ] ダイアログ ボックスで定義できます。 詳細については、「Visual Basic デバッグ構成のプロジェクト設定」または「C または C++ デバッグ構成のプロジェクト設定」を参照してください。

Assert の引数

System.Diagnostics.Trace.AssertSystem.Diagnostics.Debug.Assert は、最大で 3 つの引数を受け取ります。 最初の引数は調べる条件です。これは必ず指定します。 1 つの引数だけを使用して System.Diagnostics.Trace.Assert(Boolean) または System.Diagnostics.Debug.Assert(Boolean) を呼び出した場合、Assert メソッドによって条件がチェックされ、結果が false である場合は呼び出し履歴の内容が [出力] ウィンドウに出力されます。 System.Diagnostics.Trace.Assert(Boolean) および System.Diagnostics.Debug.Assert(Boolean) の使用例は、次のようになります。

Debug.Assert ( stacksize > 0 );
Trace.Assert ( stacksize > 0 );

2 番目と 3 番目の引数は文字列にする必要があります (存在する場合)。 System.Diagnostics.Trace.Assert または System.Diagnostics.Debug.Assert を 2 つまたは 3 つの引数を使用して呼び出すと、1 番目の引数は条件として処理されます。 メソッドはこの条件をチェックし、結果が false の場合は 2 番目と 3 番目の文字列を出力します。 2 つの引数を使用した System.Diagnostics.Debug.Assert(Boolean, String)System.Diagnostics.Trace.Assert(Boolean, String) の例を次に示します。

Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );

3 つの引数を使用した System.Diagnostics.Debug.Assert(Boolean, String, String)System.Diagnostics.Trace.Assert(Boolean, String, String) の例を次に示します。

Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );

このトピックの内容

Assert の動作のカスタマイズ

ユーザー インターフェイス モードでアプリケーションを実行した場合、条件が失敗すると、Assert メソッドによって [アサーションに失敗しました] ダイアログ ボックスが表示されます。 アサーションが失敗した場合に発生するアクションは、Listeners プロパティまたは Listeners プロパティによって制御されます。

出力動作をカスタマイズするには、TraceListener オブジェクトを Listeners コレクションに追加するか、TraceListenerListeners コレクションから削除します。または、既存の System.Diagnostics.TraceListener.FailTraceListener メソッドをオーバーライドして動作を変更します。

たとえば、System.Diagnostics.TraceListener.Fail メソッドをオーバーライドして、[アサートに失敗しました] ダイアログ ボックスに表示する代わりに、イベント ログに書き込むことができます。

この方法で出力をカスタマイズするには、プログラムにリスナーが含まれている必要があります。また、TraceListener を継承し、その System.Diagnostics.TraceListener.Fail メソッドをオーバーライドする必要があります。

詳細については、「トレース リスナー」を参照してください。

このトピックの内容

構成ファイルでのアサーションの設定

アサーションは、コード内だけでなく、プログラム構成ファイル内でも設定できます。 詳細については、System.Diagnostics.Debug.AssertSystem.Diagnostics.Trace.Assert」または」を参照してください。