Debug.Assert/Debug.Fail是否自动有条件地编译为#if "DEBUG"?或者说,如果没有调试器(即使在发布版本中),它只是不会执行任何操作?如果是这样,那么将它们留在代码中是否会对性能产生影响?或者它们真的不应该出现在生产代码中,只用于测试或条件代码?
不,如果符号没有定义,则整个调用(包括任何表达式的评估)都将从编译中删除。 这非常重要-如果表达式中存在任何副作用,并且未定义DEBUG,则这些副作用不会发生。 下面是一个简短但完整的程序来演示:
using System;
using System.Diagnostics;
class Test
{
static void Main()
{
int i = 0;
Debug.Assert(i++ < 10);
Console.WriteLine(i);
}
}
如果定义了DEBUG
,则打印出1,否则打印出0。
由于这种行为,您无法在有条件编译的方法上拥有一个out
参数:
using System;
using System.Diagnostics;
class Test
{
static void Main()
{
int i ;
MethodWithOut(out x);
}
[Conditional("FOO")]
static void MethodWithOut(out int x)
{
x = 10;
}
}
这导致了以下错误:
Test.cs(13,6): 错误 CS0685:带有out参数的条件成员 'Test.MethodWithOut(out int)' 无法使用
Debug.Assert/Fail API中含有一个ConditionalAttribute属性,该属性的值为"DEBUG",如下所示
[Conditional("DEBUG")]
public void Assert(bool condition)
C#和VB编译器只有在代码中编译方法调用时定义了常量DEBUG时,才会实际包含对is方法的调用。如果没有定义,IL将省略方法调用。
是的,基本上如此。调试方法被装饰了 [Conditional("DEBUG")] 属性,因此如果定义了 DEBUG 符号,则对调试方法的调用不会编译到 IL 中。
有关 ConditionalAttribute 的更多信息,请参见 MSDN。