我遇到了一行代码如下:
if (condition)
// Someone added a comment here
return "something";
return "something else";
我认为总会返回“某些东西”,但事实并非如此,尽管评论if / condition的工作原理与开发人员的意图相同。
我一直在努力为此找到规则。规则是当存在无支撑条件时执行下一个有效的实际代码行,就好像它是在括号中一样?所以在有效的代码行之前我可以拥有尽可能多的空行和注释吗?
答案 0 :(得分:1)
从概念上讲,程序是使用三个步骤编译的:
- 转换,将文件从特定字符库和编码方案转换为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输出:
.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
更清洁的一个显示相同的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
答案 1 :(得分:0)
我认为总会返回“某事”,但那不是真的
不,如果condition
为true
,则返回"something"
。它按预期工作,评论不包括在该代码的评估中。看到这个小提琴:https://dotnetfiddle.net/gHtu5L