if语句中的常量条件
有时我发现预处理程序指令对我的应用程序来说不够灵活,所以我一直在想是否有可能交换预处理程序的#if
功能。if语句中的常量条件
例子:
const bool Debug = false;
if (Debug)
{
...
}
将if语句,其内容由编译删除?或者,如果Debug
常数的值为true
,编译器是否会删除条件检查并保留其内容?
if语句及其内容是否会被编译器删除?或者,如果Debug常量的值为true,编译器是否会删除条件检查并将内容保留在原位?
是的,是的。但是,这些是实现细节,不是语言的保证。
使用if(false)
控制条件编译的一些有趣的方面:
的编译是不是条件可言; if
的主体将像其他任何代码一样被编译。如果它包含语法错误,则会出现语法错误。如果它包含重载解析错误,你会得到重载解析错误。 “转到使用”和其他IDE功能继续工作。
这是从与#if false
控制非常不同;由于预处理器而被忽略的文本被视为注释。 “转到使用”不会找到有条件编译的用法,您不会获得语法着色等等。但是,代码可以完全破解,因为毕竟它基本上只是一个评论。
然而,第一点是轻微的谎言;有一个区别。内部if(false)
代码不检查明确分配错误:
int x;
if (false)
Console.WriteLine(x); // no error!
因为毕竟有没有办法,X向它是写在这个节目片段之前必须阅读!
if语句及其内容会被编译器删除吗?
是的,即使您在Debug模式下编译,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
始终执行。
这是真的,这也可以通过试图将黄色执行箭头拖到静态死亡分支中来看出。它不会工作(这可能是一个调试问题)。 – usr 2012-03-22 22:25:37
你试图看看MSIL – 2012-03-22 22:20:02
下载Linqpad,你可以在2分钟内验证自己直。 – BrokenGlass 2012-03-22 22:23:20
对于'const'成员,'if'语句将消失。对于静态只读成员,声明将保留。 – dlev 2012-03-22 22:25:03