if语句中的常量条件

时间:2012-03-22 22:18:09

标签: c#

有时我发现预处理程序指令对我的应用程序来说不够灵活,所以我一直想知道是否可以交换预处理器的#if功能。

示例:

const bool Debug = false;
if (Debug)
{
    ...
}

编译器会删除if语句及其内容吗?或者,如果Debug常量的值为true,编译器是否会删除条件检查并保留内容?

2 个答案:

答案 0 :(得分:11)

  

编译器会删除if语句及其内容吗?或者,如果Debug常量的值为true,编译器是否会删除条件检查并保留内容?

是的,是的。但是,这些是实现细节,而不是语言的保证。

使用if(false)控制条件编译的一些有趣方面:

编译根本没有条件; if的主体将像任何其他代码一样进行编译。如果它包含语法错误,您将收到语法错误。如果它包含重载解析错误,您将获得重载解析错误。 “转到使用”,其他IDE功能继续有效。

这与使用#if false控制非常不同;由于预处理程序而被省略的文本被视为注释。 “转到用法”将找不到有条件编译的用法,您不会获得语法着色,等等。但是,代码可以完全破解,因为毕竟它基本上只是一个注释。

然而,第一点是轻微的谎言;有一点不同。未检查if(false)内的代码是否存在明确的分配错误:

int x;
if (false)
    Console.WriteLine(x); // no error!

因为毕竟,在用这个程序片段写入之前,x是无法读取的!

答案 1 :(得分:3)

  

编译器会删除if语句及其内容吗?

是的,即使您在调试模式下编译,if语句也将从生成的IL中删除。

  

或者,如果Debug常量的值为true,那么   编译器删除条件检查并保留内容?

是的,即使你在调试模式下编译也会发生这种情况。

例如:

static void Main()
{
    const bool Debug = false;
    if (Debug)
    {
        Console.WriteLine("ok");
    }
}

产生以下IL:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: ret 
}

正如您所看到的,该方法的整个主体已从IL中删除

static void Main()
{
    const bool Debug = true;
    if (Debug)
    {
        Console.WriteLine("ok");
    }
}

结果:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: ldstr "ok"
    L_0005: call void [mscorlib]System.Console::WriteLine(string)
    L_000a: ret 
}

此处始终执行Console.WriteLine而不执行任何if