14

我尝试了以下代码:

class Magic {
   [Conditional("DEBUG")]
   public static void DoMagic( int stuff )
   {
   }
   public static int ComputeMagic()
   {
      throw new InvalidOperationException();
   }
}
class Program
{
   static void Main(string[] args)
   {
      Magic.DoMagic(Magic.ComputeMagic());
   }
}

并且看起来在 Release 构建中没有抛出异常,因此不仅删除了对标记为的方法的调用ConditionalAttribute,而且还消除了参数计算。

这种行为有保证吗?

4

2 回答 2

19

是的,参数评估在DEBUG未定义时被删除(这在发布版本中很典型)。

来自https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#reserved-attributes

如果定义了符号,则包含调用;否则,调用(包括调用参数的评估)将被省略。

于 2014-02-21T13:14:29.583 回答
11

是的,一切都被删除了。这对于避免仅与(例如)日志记录相关的昂贵计算非常有用,但这意味着您需要小心不要消除必要的副作用。例如:

Trace(SomethingCritical());

与以下非常不同:

var result = SomethingCritical();
Trace(result);

或在您的特定情况下:

DoMagic(ComputeMagic()); // everything here done only if DEBUG symbol defined

相对

var result = ComputeMagic(); // always done
DoMagic(result); // done only if DEBUG symbol defined

从规范§17.4.2(强调我的):

如果定义了符号,则包含调用;否则,调用(包括接收者的评估和调用的参数)被省略。

于 2014-02-21T13:17:20.547 回答