【发布时间】:2009-03-07 23:40:50
【问题描述】:
Debug.Assert/Debug.Fail 是否自动条件编译#if "DEBUG"?或者它更像是如果没有附加调试器(即使在发布中)它只是没有做很多事情?如果是这样,将它们留在代码中是否会对性能产生影响?或者他们真的不打算在生产代码中,只是测试或条件代码?
【问题讨论】:
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: 条件成员 'Test.MethodWithOut(out int)' 不能 有一个out参数
【讨论】:
Debug.Assert/Fail API 包含一个 ConditionalAttribute 属性,其值为“DEBUG”,如下所示
[Conditional("DEBUG")]
public void Assert(bool condition)
如果在代码中编译方法调用时定义了常量 DEBUG,则 C# 和 VB 编译器实际上只会包含对 is 方法的调用。如果不存在,则方法调用将从 IL 中省略
【讨论】:
是的,差不多。 Debug 方法用 [Conditional("DEBUG")] 属性修饰,因此如果定义了 DEBUG 符号,则对 Debug 方法的调用不会编译到 IL 中。
有关 ConditionalAttribute 的更多信息,请访问 MSDN。
【讨论】: