C# 在单行条件下省略大括号的具体规则是什么

C# 在单行条件下省略大括号的具体规则是什么,c#,C#,我遇到了一行代码,如下所示: if (condition) // Someone added a comment here return "something"; return "something else"; 我认为“something”总是会被返回,但事实并非如此,尽管有注释if/condition按照开发人员的意图工作 我一直在努力寻找这方面的规则。当存在无括号条件时,实际代码的下一个有效行是否会像在大括号中一样执行?所以在有效代码行之前,我可以有任意多的空行和注释

我遇到了一行代码,如下所示:

if (condition)
    // Someone added a comment here
    return "something";

return "something else";
我认为“something”总是会被返回,但事实并非如此,尽管有注释if/condition按照开发人员的意图工作

我一直在努力寻找这方面的规则。当存在无括号条件时,实际代码的下一个有效行是否会像在大括号中一样执行?所以在有效代码行之前,我可以有任意多的空行和注释

我以为“某物”总会被归还,但那不是真的

否,如果
条件
,则返回
“某物”
。它按预期工作,注释不包括在代码的评估中。看这把小提琴:

上面写着:

从概念上讲,程序的编译分为三个步骤:

  • 转换,将文件从特定字符库和编码方案转换为Unicode字符序列
  • 词法分析,将Unicode输入字符流转换为令牌流
  • 语法分析,将令牌流转换为可执行代码
  • 本规范介绍了C#编程语言的语法 使用两种语法。词汇语法(§2.2.2)定义了Unicode的使用方式 字符组合形成行终止符、空格、, 注释、标记和预处理指令。句法语法 (§2.2.3)定义了词汇语法产生的标记是如何使用的 合并形成C#程序

    我们可以看到,标记被组合起来形成程序,所以在前面的转换之后剩下的任何标记最终都会被编译。您的问题是关于词法分析,特别是注释、空白和新行如何影响生成的标记。答案是,除了能够分离令牌之外,它们根本不会影响它们:

    C#源文件的词法结构由五个基本元素组成: 线路终端(§2.3.1)、空白(§2.3.3)、注释(§2.3.2), 代币(§2.4)和预处理指令(§2.5)。这些基本的 元素,只有标记在C的语法中是重要的# 计划(§2.2.3)

    C#源文件的词法处理包括 将文件缩减为一系列标记,这些标记将成为输入 句法分析行终止符、空白和注释 可以用于分离令牌,预处理指令可能导致 要跳过的源文件的部分,但除此之外 元素对C程序的语法结构没有影响

    因此,您的程序可以通过新行字符、空格字符或注释来分隔标记,并且它将编译它们,就像它们不存在一样。下面是我分别编译的两个示例,显示了使用ILSpy的中间语言输出:

            static void Main(string[] args)
            {
                if
    (true
    
                    )
    
                    /* comment separating `)` token from the `Console` token */
    
                    Console.WriteLine("something") /* another comment, semicolon token to the right */;
                else                                          // bunch of white space to the left
                    Console.
    WriteLine("something else")
    
    
    
    ;
    
            }
    
    Main()方法的ILSpy输出:

    清洁剂显示相同的ILSpy输出:

    static void Main(string[] args)
    {        
        if (true) Console.WriteLine("something"); else Console.WriteLine("something else");
    }
    
    第二版本的ILSpy输出:

        .method private hidebysig static
    void Main(
        string[] args
    ) cil managed
        {
    // Method begins at RVA 0x2088
    // Code size 17 (0x11)
    .maxstack 1
    .entrypoint
    .locals init (
        [0] bool
    )
    
    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: ldstr "something"
    IL_0008: call void[mscorlib]
        System.Console::WriteLine(string)
    IL_000d: nop
    IL_000e: br.s IL_0010
    
    
    IL_0010: ret
    } // end of method Program::Main
    

    好的假设。试试看,规则是按照你所说的去做的。明智的程序员总是使用大括号!“对于单个语句,大括号是可选的,但建议使用。”“尽管有注释”-编译器忽略comments@KernelMode-关于?谢谢。这就是我所希望的解释。
        .method private hidebysig static
    void Main(
        string[] args
    ) cil managed
        {
    // Method begins at RVA 0x2088
    // Code size 17 (0x11)
    .maxstack 1
    .entrypoint
    .locals init (
        [0] bool
    )
    
    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: ldstr "something"
    IL_0008: call void[mscorlib]
        System.Console::WriteLine(string)
    IL_000d: nop
    IL_000e: br.s IL_0010
    
    
    IL_0010: ret
    } // end of method Program::Main