条件属性是否也消除了子表达式?

时间:2013-07-31 09:20:14

标签: c# mono conditional-compilation

我有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编译器的情况。

4 个答案:

答案 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您可以阅读有关它们的文档。

希望它有所帮助。

相关问题