回答:
Assertを使用しない理由はわかりません。そうすることで、前提条件や不変条件などのガードの必要性をすでに認識しており、Design by Contractに向かって動き始めています。アサートはこれを達成する1つの方法にすぎません...
// Precondition using Asert
void SomeMethod(Foo someParameter)
{
Debug.Assert(someParameter != null)
}
// Precondition using If-Then-Throw
void SomeMethod(Foo someParameter)
{
if (someParameter == null)
throw new ArgumentNullException("someParameter");
}
// Precondition using Code Contracts
void SomeMethod(Foo someParameter)
{
Contract.Requires(someParameter != null);
}
// Precondition using some custom library
void SomeMethod(Foo someParameter)
{
Require.ArgumentNotNull(() => someParameter);
}
すべてが同じこと、つまりコードの堅牢性を達成する方法です。オプションを選択するだけで、その中のAssertが有効な選択です。
ユニットテストは非常に異なることを達成するため、これまでのところユニットテストについては言及していません。単体テストは、ガードを実行することにより、コードの堅牢性を正式に証明します。
[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
delegate call = () => someObject.SomeMethod(null);
Assert.That(call).Throws<ArgumentNullException>();
}
これはまったく異なる種類のアサートです...
**一部のフレームワークでは、アサーションの失敗がランタイム全体をダウンさせる可能性があるため、実際にはアサーションの失敗の単体テストが非常に難しいことに注意してください。
私は最近、Debug.Assertを時期尚早な最適化と見なしています。本当にパフォーマンスが必要でない限り、リリースモードでアサートを抑制すると、バグをより長く隠すことができます。
MattDaveyが指摘するように、コードコントラクトは優れている可能性があり、動的チェックの代わりに静的チェックを提供します。利用できない場合は、Trace.Assertまたは単純なif(x) throw SomeException;
Debug
クラスのメソッドへのすべての呼び出しがコンパイルからスキップされることに言及する価値があります...したがって、Assert
単にパフォーマンスのために呼び出しを抑制することは、早すぎる最適化ではなく、単なるナンセンスです。