2

我有 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

4 回答 4

2

func2 不会被调用。在 C# 语言规范中有说明,因此 Mono 编译器必须按照这些规则行事。

MSDN http://msdn.microsoft.com/en-us/library/aa664622(v=vs.71).aspx

Conditional 属性允许定义条件方法。Conditional 属性通过测试条件编译符号来指示条件。根据在调用点是否定义了此符号,是否包含或省略对条件方法的调用。如果定义了符号,则包含调用;否则,调用(包括调用参数的评估)将被省略。

于 2013-07-31T09:24:53.740 回答
1

func2()不会被调用,因为调用func1()将被完全删除。

如果您打算将此功能用于断言,您可能需要考虑使用Code Contracts.

您将能够添加参数验证和其他断言,可以选择从发布版本中完全剥离(有一个后处理器进行剥离)。

要验证参数,您可以执行以下操作:

public void Test(int value)
{
    Contract.Requires((0 < value) && (value < 10));
    // ...
}

你可以断言这样的条件:

Contract.Assume(something != 0);
于 2013-07-31T09:32:23.800 回答
0

线

func1(func2());

如果 DEBUG == false 将被删除

于 2013-07-31T09:24:00.197 回答
0

在 c# 中也有宏,但它们与 c++ 不同。

您可以在中声明一个宏Conditional Compilation Symbols并像这样检查它们

#if MACRO
#endif

在这里您可以阅读有关它们的文档。

希望能帮助到你。

于 2013-07-31T09:26:22.900 回答