メソッドの事前条件と事後条件をチェックするための (非常に小さな) フレームワークを作成しています。エントリ ポイントは次のとおりです (簡単にメソッドにすることができますが、それは問題ではありません)。
public static class Ensures {
public static Validation That {
get { ... }
}
}
public static class Requires {
public static Validation That {
get { ... }
}
}
明らかに、事後条件のチェックはコストがかかる可能性があり、メソッドにバグがない場合は実際には必要ありません。したがって、次のように機能するメソッドが必要です。
public static class Ensures {
[ConditionalCallingCode("DEBUG")]
public static Validation ThatDuringDebug {
get { ... }
}
}
whereConditionalCallingCodeAttribute
は、呼び出しコードが DEBUG シンボルを定義してコンパイルされている場合にのみ、このメソッドを実行する必要があることを意味します。これは可能ですか?
クライアントコードを次のようにしたい:
public class Foo {
public void Bar() {
... // do some work
Ensures.That // do these checks always
.IsNotNull(result)
.IsInRange(result, 0, 100);
Ensures.WhileDebuggingThat // only do these checks in debug mode
.IsPositive(ExpensiveCalculation(result));
return result;
}
}
もちろん、WhileDebuggingThat を提供することはできません。次に、クライアント コードは次のようになります。
public class Foo {
public void Bar() {
... // do some work
Ensures.That // do these checks always
.IsNotNull(result)
.IsInRange(result, 0, 100);
#ifdef DEBUG
Ensures.That // only do these checks in debug mode
.IsPositive(ExpensiveCalculation(result));
#endif
return result;
}
}
これは、他に何もうまくいかない場合のフォールバック プランですが、DRY がひどく壊れます。
私が理解しているように、でマークWhileDebuggingThat
すると、このライブラリを参照するアセンブリではなく[Conditional("DEBUG")]
、ライブラリのコンパイル中に DEBUG が定義されているかどうかに応じて、このメソッドが発行されます (または発行されません) 。したがって、これを行ってから、ライブラリのユーザーに、コードのデバッグ ビルドをライブラリのデバッグ ビルドにリンクし、リリース ビルドをリリース ビルドにリンクするように指示するドキュメントを作成できます。これは最善の解決策とは思えません。
最後に、ライブラリのユーザーに、プロジェクト内でこのクラスを定義するように指示できます。
using ValidationLibrary;
public static class EnsuresWhileDebugging {
[Conditional("DEBUG")]
public static Validation That() {
return Ensures.That;
}
}
私が見る限り、これも同様に機能するはずですが、DRY の原則を少しでも破る必要があります。