Debug.Assert / Debug.Fail是否自动有条件地编译#if“DEBUG”?或者更像是没有附加调试器(即使在发布中)它只是没有做太多的事情?如果是这样,将它们留在代码中会有性能影响吗?或者它们真的不是生产代码,只是测试或条件代码?
答案 0 :(得分:16)
不,如果未定义符号,则从编译中删除整个调用,包括任何表达式评估。这非常重要 - 如果表达式中存在任何副作用,如果未定义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参数
答案 1 :(得分:6)
Debug.Assert / Fail API包含一个ConditionalAttribute属性,其值为“DEBUG”,如此
[Conditional("DEBUG")]
public void Assert(bool condition)
如果在代码中编译方法调用时定义了常量DEBUG,则C#和VB编译器实际上只包含对is方法的调用。如果不存在,方法调用将从IL
中省略答案 2 :(得分:2)
是的,差不多。 Debug方法使用[Conditional(“DEBUG”)]属性进行修饰,因此如果定义了DEBUG符号,则不会将对Debug方法的调用编译到IL中。
有关MSDN ConditionalAttribute的更多信息。