Debug.Assert/Debug.Fail是否会自动根据条件编译#if "DEBUG"?

6
Debug.Assert/Debug.Fail是否自动有条件地编译为#if "DEBUG"?或者说,如果没有调试器(即使在发布版本中),它只是不会执行任何操作?如果是这样,那么将它们留在代码中是否会对性能产生影响?或者它们真的不应该出现在生产代码中,只用于测试或条件代码?

请参阅https://dev59.com/JEbRa4cB1Zd3GeqP1paf。 - Brian
3个回答

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:带有out参数的条件成员 'Test.MethodWithOut(out int)' 无法使用


6

Debug.Assert/Fail API中含有一个ConditionalAttribute属性,该属性的值为"DEBUG",如下所示

[Conditional("DEBUG")]
public void Assert(bool condition)

C#和VB编译器只有在代码中编译方法调用时定义了常量DEBUG时,才会实际包含对is方法的调用。如果没有定义,IL将省略方法调用。


F12元数据显示属性,您只需在其前展开注释/折叠块即可。 - Luke Puplett

2

是的,基本上如此。调试方法被装饰了 [Conditional("DEBUG")] 属性,因此如果定义了 DEBUG 符号,则对调试方法的调用不会编译到 IL 中。

有关 ConditionalAttribute 的更多信息,请参见 MSDN。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接