代码之家  ›  专栏  ›  技术社区  ›  Neelam Prajapati

未定义的变量在使用if检查时不应该引发异常吗?

c#
  •  1
  • Neelam Prajapati  · 技术社区  · 6 年前
    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();
        }
    }
    

    输出:


    好啊

    有人能给我解释一下吗?如果 pi 没有定义,是否应该引发异常?

    3 回复  |  直到 6 年前
        1
  •  5
  •   Ahmed Abdelhameed    6 年前

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

    documentation 以下内容:

    当C编译器遇到 #if 指令,遵循 最后通过一个endif指令,它编译 指令 仅当定义了指定符号时 是的。不像C和C++, 不能为符号指定数值。c中的if语句# 是布尔型的,仅测试 是否定义了符号 是的。

    此外:

    #define 用于定义符号。然后使用符号作为传递给 #如果 指令,表达式计算为 是的。

    因此,如果符号( pi 在您的情况下)还没有定义,结果总是错误的。

        2
  •  3
  •   take    6 年前

    αif条件是一个预处理器指令。

    条件之间的代码仅在定义了条件时编译,或者在您的情况下,如果 pi 未定义 #if !pi 是的。

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

        3
  •  2
  •   MakePeaceGreatAgain    6 年前

    您似乎对预处理器指令是什么感到困惑。因为名称已经表明它是编译器评估的东西。因此,两个分支中的哪一个被烘焙到组件中是在 滑稽剧 -时间。这意味着只有一个在汇编中存在,另一个在编译时被省略,参见下面的IL pi 未定义:

     .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          
    
      }
    

    什么时候? 圆周率 定义的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          
    
      }
    

    如您所见,编译的程序集因符号是否定义而有所不同。

    所以 有效地 如果 圆周率 已定义(请参阅第一个IL代码)

    Console.WriteLine("i");
    Console.WriteLine("ok");
    Console.ReadLine();
    

    和(见第二个IL代码)

    Console.WriteLine("PI undefined");
    Console.WriteLine("ok");
    Console.ReadLine();
    

    如果没有定义。

    如您所见,代码不可能导致异常 圆周率 未定义为 圆周率 在编译的程序集中根本不存在。