使用new关键字时为什么不需要括号?

Mic*_*ael 2 c#

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

var files = (new DirectoryInfo(@"C:\Temp")).GetFiles();
Run Code Online (Sandbox Code Playgroud)

但是,以下也有效(请注意"new"关键字之前缺少括号):

var files = new DirectoryInfo(@"C:\Temp").GetFiles();
Run Code Online (Sandbox Code Playgroud)

为什么允许这种情况发生?声明如下:

2 + 4 * 3   and   (2 + 4) * 3
Run Code Online (Sandbox Code Playgroud)

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

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

即:

2   +  4               * 3
new    DirectoryInfo()   .GetFiles()
Run Code Online (Sandbox Code Playgroud)

VS:

(2   +  4              ) * 3
(new    DirectoryInfo())   .GetFiles()
Run Code Online (Sandbox Code Playgroud)

为什么会出现这种情况,有一个简单的解释吗?C#词法分析器处理这两种情况(有/无括号)不是更有效吗?我的比喻有缺陷吗?

Jon*_*eet 8

注意:这个答案有很多表达方式,它们彼此相同.我没有将它们保持内联或将它们分成两个单独的行,而是采用了一种简写<==>来表示"相当于".所以

foo   <==>   bar
Run Code Online (Sandbox Code Playgroud)

应该被理解为"表达式foo等同于表达式bar".

你所谈论的是优先权.*具有比二元+运算符更高的优先级,因此它"更紧密地绑定其操作数".所以:

 x * y + z   <==>   (x * y) + z
Run Code Online (Sandbox Code Playgroud)

两者new和"点"部分都是主要表达式,它们具有相同的优先级.当两个表单具有相同的优先级时,将涉及关联性.当涉及到new运算符时,C#规范实际上并不十分清楚,但.运算符是二元运算符,并且所有二元运算符都被认为是左关联的.换一种说法:

x.y.z   <==>   (x.y).z
Run Code Online (Sandbox Code Playgroud)

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

x * y / z   <==>   (x * y) / z
x / y * z   <==>   (x / y) * z
Run Code Online (Sandbox Code Playgroud)

因此:

new DirectoryInfo(x).GetFiles()   <==>   (new DirectoryInfo()).GetFiles()
Run Code Online (Sandbox Code Playgroud)

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

x + y * z   <==>   x + (y * z)
Run Code Online (Sandbox Code Playgroud)

...但是它仍然x是先评估y,然后是z,然后是乘法,然后是最后的加法.正常情况下,Eric Lippert在这个话题上写得非常好.