我今天读到了Conditional
属性。根据MSDN:
将
ConditionalAttribute
应用于方法指示编译器不应将对该方法的调用编译为Microsoft中间语言(MSIL),除非定义了与ConditionalAttribute
关联的条件编译符号。 / p>
行。这很清楚。因此,对方法的调用将不会被编译。但副作用呢?
[Conditional("UndefinedCondition")]
static void f1(int x) { Console.WriteLine(x); }
static int a = 0;
static void f2() { f1(++a); }
因此,当调用f2
时,应删除对f1
的调用。但为什么++a
也被删除了?这对我没有任何意义!
答案 0 :(得分:5)
是的,参数所需的任何调用也会被删除。这意味着对于典型的用例(调试版本),您将删除整个表达式,这通常是预期的。
基本上,在使用[Conditional]
方法,或(在C#3.0中)部分方法时,您需要非常小心 - 这些方法具有非常相似的行为如果部分方法的另一半未实现。作为示例(对于部分方法),请参见下文。请注意,已移除对HasSideEffect()
的调用(取消注释Bar
的另一半以查看其是否有效):
using System;
partial class Foo {
partial void Bar(string value);
static void Main() {
Foo foo = new Foo();
foo.Bar(HasSideEffect());
}
static string HasSideEffect() {
Console.WriteLine("hello");
return "world";
}
}
partial class Foo {
/* uncomment this
partial void Bar(string value) {
Console.WriteLine(value);
}*/
}
答案 1 :(得分:5)
扩展Marc的答案。
这绝对是“按设计”。理解这种合理化的最好方法是考虑这个代码取而代之的是什么。这个功能以许多更清晰的方式采用了有条件编译的代码。
例如,
#if DEBUG
f1(++a);
#endif
或其他版本
#define f1(x) ...
在非调试的情况下,显然没有副作用。这与[条件]代码的行为相同。我同意它肯定不如第一个例子那么清楚,但它与第二个例子一样清晰。
答案 2 :(得分:1)
我想这是因为编译器的实现很容易。
无论如何我会害怕这些代码(即使它按预期工作)并将其写为
++a;
f1(a);
为了清楚起见。您总是可以看到执行的内容和不执行的内容。
答案 3 :(得分:1)
我还怀疑此行为的设计与C预处理器宏相同,后者通常设置为在不使用时不评估参数。