次の方法で共有


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

更新 : 2007 年 11 月

このトピックの内容は、次の製品に該当します。

Edition

Visual Basic

C#

C++

Web Developer

Express

トピック該当 トピック該当 トピック該当なし トピック該当

Standard

トピック該当 トピック該当 トピック該当なし トピック該当

Pro/Team

トピック該当 トピック該当 トピック該当なし トピック該当

表の凡例 :

トピック該当

対象

トピック該当なし

該当なし

トピックは該当しますが、コマンドは既定では非表示です

既定で非表示のコマンド

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

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

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

Debug.Assert メソッド

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

[Visual Basic]

Function IntegerDivide(ByVal dividend As Integer, ByVal divisor As Integer) As Integer
    Debug.Assert(divisor <> 0)
    Return CInt(dividend / divisor)
End Function

[C#]

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

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

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

[Visual Basic]

Dim amount, balance As Double
balance = savingsAccount.balance
Debug.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)

[C#]

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

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

[Visual Basic]

Dim amount, balance As Double
balance = savingsAccount.balance
Trace.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)

[C#]

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

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

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

Debug.Assert の副作用

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

[Visual Basic]

' unsafe code
Debug.Assert (meas(i) <> 0 )

[C#]

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

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

[Visual Basic]

temp = meas( i )
Debug.Assert (temp <> 0)

[C#]

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

Trace.Assert を使用する場合でも、Assert ステートメント内に関数呼び出しを配置しないようにします。Trace.Assert ステートメントはリリース ビルドで除去されないため、関数呼び出しは安全です。しかし、そのような構造体を避ける習慣を付けておくことで、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 メソッドを使用する必要がある場合は、リリース構成に DEBUG シンボルを定義する必要があります。

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

Assert の引数

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

[Visual Basic]

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

[C#]

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

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

[Visual Basic]

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

[C#]

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

Assert および Assert の使用例は、次のようになります。

[Visual Basic]

Debug.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:", "inctemp failed on third call" )

[C#]

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 コレクションに追加するか、TraceListener を Listeners コレクションから削除します。または、既存の TraceListener の TraceListener.Fail メソッドをオーバーライドして動作を変更します。

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

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

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

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

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

参照

処理手順

方法 : トレースとデバッグを指定して条件付きコンパイルを実行する

概念

デバッガのセキュリティ

参照

Debug.Assert

Trace.Assert

その他の技術情報

アプリケーションのトレースとインストルメント

デバッグの準備 : プロジェクトの種類が C# および Visual Basic のプロジェクト

マネージ コードのデバッグ