2

如果我想获取某个目录中所有文件的列表,我可以输入如下内容:

var files = (new DirectoryInfo(@"C:\Temp")).GetFiles();

但是,以下内容也有效(注意“new”关键字之前缺少括号):

var files = new DirectoryInfo(@"C:\Temp").GetFiles();

为什么允许这种情况发生?像这样的陈述:

2 + 4 * 3   and   (2 + 4) * 3

由于括号,将分别解析为 14 和 18。

看起来我的代码示例类似于在 DirectoryInfo 对象的静态版本上调用“.GetFiles()”方法(因为缺少“new”关键字),其中括号与“new”关键字结合明确说明我正在使用 DirectoryInfo 对象的一个​​实例。

IE:

2   +  4               * 3
new    DirectoryInfo()   .GetFiles()

与:

(2   +  4              ) * 3
(new    DirectoryInfo())   .GetFiles()

是否有一个简单的解释来解释为什么会这样?C# 词法分析器处理这两种情况(带/不带括号)不是更多的工作吗?我的比喻有问题吗?

4

5 回答 5

8

注意:这个答案有很多相互等价的表达方式。我没有将它们保持内联或将它们分成两行,而是采用了一种简写形式<==>来表示“相当于”。所以

foo   <==>   bar

应理解为“表达式foo等价于表达式bar”。

你说的是优先级*比二元运算符具有更高的优先级+,因此它更紧密地“绑定其操作数”。所以:

 x * y + z   <==>   (x * y) + z

两者new和“点”部分都是主要表达式,它们具有相同的优先级。当两种形式具有相同的优先级时,就会涉及关联性。C# 规范在操作符方面实际上并不是很清楚new,但.操作符是二元运算符,所有二元运算符都被认为是左关联的。换句话说:

x.y.z   <==>   (x.y).z

再举一个例子,*并且/具有相同的优先级,所以:

x * y / z   <==>   (x * y) / z
x / y * z   <==>   (x / y) * z

所以:

new DirectoryInfo(x).GetFiles()   <==>   (new DirectoryInfo()).GetFiles()

所有这些都与评估顺序有些不同,评估顺序总是从左到右。例如,在表达式x + y * z中,较高的优先级*意味着:

x + y * z   <==>   x + (y * z)

...但它仍然x是首先评估的,然后是y,然后z是 ,然后是乘法,最后是加法。像往常一样,Eric Lippert 在这个主题上写得非常好

于 2012-11-26T21:06:55.937 回答
4

请参阅 MSDN 上有关优先级的文章: 7.2.1

由于所有非赋值二元运算符都是左结合的,因此同等先例new.运算符是从左到右计算的。

因此,在给定的表达式中,对象在其方法被调用之前被实例化。此外--new具有同等优先级,因此它在获取类型标识符之前会使用类型标识符(从左到右).

于 2012-11-26T21:02:02.260 回答
3

调用静态方法的语法 isDirectoryInfo.GetFiles()和 not DirectoryInfo(...).GetFiles(),所以我不确定这两种解释之间如何存在冲突。

无论哪种方式,您使用数字表达式的示例都将首先乘以 3,因为乘法的优先级高于加法或减法。括号所做的只是允许您覆盖默认优先级。

即使调用静态方法的语法相同,在您询问的情况下,默认优先级仍然会导致它在没有括号的情况下按预期工作。

于 2012-11-26T20:57:59.093 回答
2

您不能new返回值,因此编译器知道将 new 与初始化类型一起放入,并在新实例上运行该方法。

(new A()).Foo() // Makes sense! sort of...
new (A().Foo()) // Makes absolute no sense.

(1 + 4) * 10 // Makes sense
1 + (4 * 10) // Also makes sense

数字和 C# 关键字之间的事物如何协同工作的逻辑有所不同。

于 2012-11-26T20:59:18.440 回答
1

您的类比适用于数学中的运算顺序。但是在语法上使用 new 表示编译器为类的“新”实例做好准备。括号与否,您可以使用关键字 new 获得该类的新实例。

于 2012-11-26T20:58:59.303 回答