マネージ コードのアサーション
更新 : 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.Assert を Trace.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.Assert と Debug.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」を参照してください。
参照
処理手順
方法 : トレースとデバッグを指定して条件付きコンパイルを実行する