【发布时间】:2010-09-28 12:55:05
【问题描述】:
我正在编写一个(非常小的)框架来检查方法的前置条件和后置条件。入口点是(它们很容易成为方法;没关系):
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 { ... }
}
}
其中ConditionalCallingCodeAttribute 表示该方法只应在调用代码编译时使用定义的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。
据我了解,用[Conditional("DEBUG")] 标记WhileDebuggingThat 将发出(或不发出)此方法,具体取决于在库编译期间是否定义了DEBUG,不是引用的程序集这个图书馆。所以我可以这样做,然后编写文档告诉库用户将其代码的调试版本与库的调试版本链接起来,并将发布版本与发布版本联系起来。我觉得这并不是最好的解决方案。
最后,我可以告诉图书馆用户在他们的项目中定义这个类:
using ValidationLibrary;
public static class EnsuresWhileDebugging {
[Conditional("DEBUG")]
public static Validation That() {
return Ensures.That;
}
}
据我所知,这应该也可以,但仍然需要打破 DRY 原则,即使只是轻微的。
【问题讨论】:
-
这不就是断言的用途吗?
-
断言用于检查后置条件(并且仅在调试版本中;我也希望允许在发布版本中保留后置条件检查),而不是验证前置条件。
标签: c# build debugging release conditional-compilation