我Conditional
今天读到了这个属性.根据MSDN:
应用于
ConditionalAttribute
方法指示编译器不应将对方法的调用编译为Microsoft中间语言(MSIL),除非ConditionalAttribute
定义了与之关联的条件编译符号.
好.这很清楚.因此不会编译对该方法的调用.但副作用呢?
[Conditional("UndefinedCondition")] static void f1(int x) { Console.WriteLine(x); } static int a = 0; static void f2() { f1(++a); }
因此,当f2
被调用时,f1
应该删除调用.但为什么也被++a
删除了?这对我没有任何意义!
是的,参数所需的任何调用也会被删除.这意味着对于典型的用例(调试版本),您将删除整个表达式,这通常是预期的.
基本上,在使用任一[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); }*/ }
扩展Marc的答案.
这绝对是"按设计".理解这种合理化的最好方法是考虑这个代码取而代之的是什么.这个功能以许多更清晰的方式采用了有条件编译的代码.
例如,
#if DEBUG f1(++a); #endif
或者另一个版本
#define f1(x) ...
在非调试的情况下,显然没有副作用.这与[条件]代码的行为相同.我同意它肯定不如第一个例子那么清楚,但它与第二个例子一样清晰.