C#-Assert()メソッドは何をしますか?それはまだ役に立ちますか?


156

ブレークポイントを使用してデバッグしていて、アサート呼び出しを認識していますか?単体テストだけだと思いました。ブレークポイント以上のことは何ですか?ブレークポイントを設定できるので、なぜAssertを使用する必要があるのですか?


9
ちなみに、アサートに関心がある場合は、コードコントラクトを詳細に調べる必要があります。
MasterMastic 2013

回答:


200

デバッグコンパイルでAssertは、ブール条件をパラメーターとして受け取り、条件がfalseの場合にエラーダイアログを表示します。条件が真の場合、プログラムは中断することなく続行します。

リリースでコンパイルした場合、すべてDebug.Assertのは自動的に除外されます。


12
リリースモードでDebug.Assertの同じ動作を取得するにはどうすればよいですか?
Hamish Grubijan、2011

15
リリースモード明らかにレフリーのためのTrace.Assert:msdn.microsoft.com/en-us/library/... msdn.microsoft.com/en-us/library/e63efys0.aspx
ティム・アベル

8
@HamishGrubijanそして、なぜDebug.Assertリリースモードにしたいのですか?
Camilo Martin

25
IMO、リリースコードからアサートを省略するのは、ドッキング中に救命艇の訓練を行い、その後、航行時に救命艇を後にするようなものです。:)
2012年

113
アサートは救命艇ではなく、氷山検出システムです。ユーザーが船を操縦していないので、リリースコードのアサートは運命にあることをユーザーに伝えます。それは彼らに氷山を避けさせない。
ステファン

97

コード完了から

8防御プログラミング

8.2アサーション

アサーションとは、開発中に使用されるコード(通常はルーチンまたはマクロ)であり、プログラムが実行中にプログラム自体をチェックできるようにします。アサーションがtrueの場合、すべてが期待どおりに動作していることを意味します。falseの場合は、コードで予期しないエラーが検出されたことを意味します。たとえば、顧客情報ファイルに50,000件を超えるレコードがないとシステムが想定している場合、プログラムには、レコード数が50,000以下であるというアサーションが含まれる場合があります。レコード数が50,000以下である限り、アサーションはサイレントになります。ただし、50,000件を超えるレコードが検出された場合は、プログラムにエラーがあることを大声で「アサート」します。

アサーションは、大規模で複雑なプログラムや信頼性の高いプログラムで特に役立ちます。これにより、プログラマーは、不一致のインターフェースの仮定、コードが変更されたときに侵入するエラーなどをより迅速に洗い出すことができます。

通常、アサーションは2つの引数を取ります。真であるはずの仮定を説明するブール式と、真でない場合に表示するメッセージです。

(…)

通常、プロダクションコードでアサーションメッセージをユーザーに表示しないようにします。アサーションは、主に開発およびメンテナンス中に使用するためのものです。アサーションは通常、開発時にコードにコンパイルされ、本番用にコードからコンパイルされます。開発中、アサーションは矛盾する仮定、予期しない条件、ルーチンに渡された不正な値などを洗い流します。本番環境では、アサーションによってシステムのパフォーマンスが低下しないように、コードからコンパイルされます。


2
この本「Writing Solid Code」にも、assertの使用法についての素晴らしい議論があります。彼らは素晴らしいデバッグツールです!
zooropa 2016

39

変数をチェックするためにコードの小さな行ごとにブレークポイントを設定する必要はないが、特定の状況が存在する場合は何らかのフィードバックを得たい場合などに、これを使用する必要があります。次に例を示します。

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

上記と同様のコード行を追加すると、プログラムを実行すると次のエラーが発生します。「エラーCS0103:名前 'Debug'は現在のコンテキストに存在しません」。機能させるために、ある種のusingステートメントが必要ですか?
Josh Desmond

4
@JoshDesmondSystem.Diagnostics
Sinjai

16

Assertは、MicrosoftのUIデザインスキルに挑戦するもう1つの機会も提供します。つまり、[中止]、[再試行]、[無視]の3つのボタンを備えたダイアログと、タイトルバーでそれらを解釈する方法の説明!


3
中止/再試行/無視は古典的です!Windows 3.1で常にこれが表示されるのは、アサーションでしたか?
devlord、2008年

これは基本的に、Windows 3.1にさかのぼるメッセージボックスを使用しており、定義済みのボタンラベルしかないためです。ハックが発生した理由は理解できますが、2008年にまだ存在している理由は理解できません。
Joe

4
@Joeこれはエンドユーザーではなく開発者だけが見るべきものなので、更新はおそらく非常に優先度の低い項目です。煩わしい場合は、Debug.ListenersまたはTrace.Listenersコレクションを変更して、デフォルトのハンドラーを必要な処理を行うハンドラーに置き換えることができます。
ダンはFirelightによって

5
さて、それは今2019年であり、同じダイアログボックス/ボタンがまだここにあります!
Bouke

10

Assertを使用すると、コードに適用される条件(postまたはpre)をアサートできます。これは、意図を文書化し、意図が満たされない場合にダイアログでデバッガーに通知させる方法です。

ブレークポイントとは異なり、アサートはコードに付属しており、意図に関する詳細を追加するために使用できます。


10

アサートは、テストとリリースの間で個別のメッセージング動作を提供するのに役立ちます。例えば、

Debug.Assert(x > 2)

リリースビルドではなく「デバッグ」ビルドを実行している場合にのみ、ブレークがトリガーされます。この動作の完全な例がここにあります


10

まず、クラスとAssert()メソッドでメソッドを使用できます。デバッグモードでのみ実行されています。デバッグおよびリリースモードで実行されています。TraceDebug
Debug.Assert()
Trace.Assert()

次に例を示します。

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

このコードをデバッグモードで実行してから、リリースモードで実行します。

ここに画像の説明を入力してください

デバッグモード中にコードDebug.Assertステートメントが失敗すると、アプリケーションの現在のスタックトレースを示すメッセージボックスが表示されます。Trace.Assert()条件がtrueであるため、これはリリースモードでは発生しません(i == 4)

WriteLine() メソッドは、単にVisual Studio出力に情報を記録するオプションを提供します。 ここに画像の説明を入力してください


5

アサーションは、Design by Contract(DbC)で大きく機能します。これは、私が理解しているように、BertandのMeyerによって導入/承認されたものです。1997.オブジェクト指向ソフトウェア構築。

重要な機能は、それらが副作用を引き起こしてはならないことです。たとえば、例外を処理したり、ifステートメント(防御的プログラミング)を使用して別のアクションを実行したりできます。

アサーションは、契約の事前/事後条件、クライアント/サプライヤーの関係をチェックするために使用されます-クライアントは、サプライヤーの事前条件が満たされていることを確認する必要があります。£5を送信し、サプライヤーはポスト条件が満たされていることを確認する必要があります。12本のバラをお届けします。(クライアント/サプライヤーの単純な説明-受け入れは少なく、多くは提供できますが、アサーションについてです)。C#では、リリースコードに使用できるTrace.Assert()も導入されています。

はい、という質問に答えるには、それらは依然として有用ですが、コードに複雑さ+可読性を追加し、時間+維持するのが困難になります。まだ使用する必要がありますか?はい、すべて使用しますか?おそらくそうではないか、マイヤーがどのように説明しているのかではありません。

(私がこのテクニックを学んだOU Javaコースでも単純な例を示しただけであり、残りのコードはほとんどのコードにDbCアサーションルールを適用しませんでしたが、プログラムの正確性を保証するために使用されると想定されていました!)


3

Debug.Assertは、メソッドの呼び出し方法に関するコントラクトを確立する方法であり、(タイプだけでなく)パラメーターの値の詳細に焦点を当てています。たとえば、2番目のパラメータでnullを送信することになっていない場合は、そのパラメータの周りにアサートを追加して、コンシューマにそれを行わないように指示します。

それは誰かがあなたのコードを骨の折れる方法で使用するのを防ぎます。しかし、それはまた、本番環境に移行するための骨の折れる方法を可能にし、顧客に厄介なメッセージを与えないようにします(リリースビルドをビルドするとします)。


6
ただし、パブリックメソッドの無効なパラメーターは引数の例外をスローする必要があることを指摘することが重要です。プライベートメソッドのみがアサーションで入力を検証する必要があります。外部から入ってくる値は常に疑わしいです!
Jeffrey L Whitledge、2008年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.