using System;
public class Program
{
public static void Main(string[] args)
{
#if (!pi)
Console.WriteLine("i");
#else
Console.WriteLine("PI undefined");
#endif
Console.WriteLine("ok");
Console.ReadLine();
}
}
输出:
i
好的
有人可以向我解释如何?如果未定义pi
,是否应该抛出异常?
答案 0 :(得分:5)
#If
指令专门检查给定符号是否已定义。
当C#编译器遇到
#if
指令时,紧随其后 最终通过#endif指令,它将在 指令仅在定义了指定符号的情况下。与C和C ++不同, 您不能将数字值分配给符号。 C#中的#if语句 是布尔值,并且仅测试是否已定义符号。
此外:
#define
可让您定义符号。然后,使用符号作为传递给#if
指令的表达式,该表达式的计算结果为 是的。
因此,如果未定义符号(在您的情况下为pi
),则结果始终为false。
答案 1 :(得分:3)
#if条件是预处理程序指令。
只有在定义了条件的情况下,才会编译条件之间的代码;或者,在没有定义pi
的情况下,则仅编译条件之间的代码。
答案 2 :(得分:2)
您似乎对预处理器指令是什么感到困惑。顾名思义,它是编译器评估的结果。因此,可以在编译时确定将两个分支中的哪个分支烘烤到组件中。这意味着它们中只有一个存在于程序集中,另一个则在编译时被忽略,如果未定义pi
,请参见以下IL:
.method public hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint
.maxstack 8
// [15 3 - 15 4]
IL_0000: nop
// [17 4 - 17 27]
IL_0001: ldstr "i"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
// [21 4 - 21 28]
IL_000c: ldstr "ok"
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: nop
// [22 4 - 22 23]
IL_0017: call string [mscorlib]System.Console::ReadLine()
IL_001c: pop
// [23 3 - 23 4]
IL_001d: ret
}
定义pi
时,IL看起来会稍有不同:
.method public hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint
.maxstack 8
// [15 3 - 15 4]
IL_0000: nop
// [19 17 - 19 51]
IL_0001: ldstr "PI undefined"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
// [21 4 - 21 28]
IL_000c: ldstr "ok"
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: nop
// [22 4 - 22 23]
IL_0017: call string [mscorlib]System.Console::ReadLine()
IL_001c: pop
// [23 3 - 23 4]
IL_001d: ret
}
如您所见,编译后的程序集根据是否定义符号而有所不同。
因此,有效地如果定义了pi
,您的源代码将与此类似(请参见第一个IL代码)
Console.WriteLine("i");
Console.WriteLine("ok");
Console.ReadLine();
和(请参阅第二个IL代码)
Console.WriteLine("PI undefined");
Console.WriteLine("ok");
Console.ReadLine();
(如果未定义)。
如您所见,代码根本不会导致pi
未定义的异常,因为pi
在已编译的程序集中根本不存在。