我有C / C ++背景。我通常在我的代码上加上严重的断言,而在C或C ++中,没有保证可以消除对子表达式的评估,这是断言参数。所以我不得不使用宏。
在C#中,我没有那种级别的宏支持。但我有Conditional
属性。根据我使用C和C ++的经验,由于副作用,子表达式无法消除。
例如,
[Conditional(DEBUG)]
void func1(int a)
{
// Do something.
}
int func2()
{
// Will this be called?
}
func1(func2());
如果仍在调用func2
,我的代码应该是isDebugMode() && func1(func2())
。但这是我真正想要避免的。所以我想知道Conditional
属性是否保证消除子表达式。
如果没有,编写调试构建断言的最佳实践是什么,它将在发布版本中完全剥离?
AFAIK,这是编译器特定的支持。我想知道Mono编译器的情况。
答案 0 :(得分:2)
将不会调用func2。它在C#语言规范中声明,因此Mono编译器必须按照这些规则行事。
MSDN http://msdn.microsoft.com/en-us/library/aa664622(v=vs.71).aspx:
Conditional属性启用条件的定义 方法。 Conditional属性通过测试a表示条件 条件编译符号。调用条件方法是 包含或省略,具体取决于是否定义了此符号 在通话时。如果定义了符号,则呼叫为 包括在内;否则,呼叫(包括评估参数 ()被省略。
答案 1 :(得分:1)
func2()
将不会被调用,因为func1()
的调用将被完全删除。
如果您打算将此功能用于断言,则可能需要考虑使用Code Contracts
。
您将能够添加参数验证和其他断言,这些断言可以选择从发布版本中完全剥离(有一个后处理器可以进行剥离)。
要验证参数,您可以执行以下操作:
public void Test(int value)
{
Contract.Requires((0 < value) && (value < 10));
// ...
}
你可以断言这样的条件:
Contract.Assume(something != 0);
答案 2 :(得分:0)
The Line
func1(func2());
如果DEBUG == false ,将被删除
答案 3 :(得分:0)
在c#中也有宏,但它们与c ++不同。
您可以在Conditional Compilation Symbols
中声明一个宏,然后像那样检查它们
#if MACRO
#endif
Here您可以阅读有关它们的文档。
希望它有所帮助。