未定义的变量是否应该在使用#if检查时抛出异常?

时间:2018-06-26 08:06:24

标签: c#

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,是否应该抛出异常?

3 个答案:

答案 0 :(得分:5)

#If指令专门检查给定符号是否已定义。

来自documentation

  

当C#编译器遇到#if指令时,紧随其后   最终通过#endif指令,它将在   指令仅在定义了指定符号的情况下。与C和C ++不同,   您不能将数字值分配给符号。 C#中的#if语句   是布尔值,并且仅测试是否已定义符号

此外:

  

#define可让您定义符号。然后,使用符号作为传递给#if指令的表达式,该表达式的计算结果为   是的。

因此,如果未定义符号(在您的情况下为pi),则结果始终为false。

答案 1 :(得分:3)

#if条件是预处理程序指令。

只有在定义了条件的情况下,才会编译条件之间的代码;或者,在没有定义pi的情况下,则仅编译条件之间的代码。

请参阅https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if

上的Microsoft文档

答案 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在已编译的程序集中根本不存在。