为什么声明不会给出CS0201编译器错误?

Swa*_*gam 2 c# oop

我对编译器错误CS0201的术语感到困惑.它说

只有赋值,调用,递增,递减和新对象表达式才能用作语句

所以除此之外的任何事情都不能成为一种说法.那么下面的行如何不会产生上述错误.

Anyclass obj;
Run Code Online (Sandbox Code Playgroud)

这里我们没有任何赋值或调用或递增或递减或新对象表达式.

我知道我遗漏了一些东西,因为官方文件与这个错误相矛盾,声明声明也是一个声明.

Eri*_*ert 17

错误文本是:

只有赋值,调用,递增,递减和新对象表达式才能用作语句

你的问题包括断言:

所以除此之外的任何事情都不能成为一种说法.

不,这是一个错误的结论.

首先,你所做的只是一个坏主意.请勿阅读错误消息以了解该语言的规则.错误消息告诉您不合法的程序有什么问题.他们不打算是一个指导,什么是合法的!写入错误消息时假定上下文是您在阅读错误的同时查看非法程序.错误消息是一个句子; 语言规范长达800页,具有更多细节. 阅读规范.

第二:正确的结论是:根据该错误消息,没有其他表达式可以用作语句.此错误消息仅在上下文中生成,其中在期望语句的上下文中使用了无效表达式.

那么下面的行如何不会产生上述错误.

Anyclass obj;
Run Code Online (Sandbox Code Playgroud)

该行不是表达式,因此错误消息不适用于它.

您从此错误消息中得出了错误的结论,这证明此错误消息令人困惑,仅仅因为这个原因,我们可以争辩说它可能会被更改.例如,我们可以说"表达式语句"而不是"语句".或者我们可以诊断出更大的问题,并报告"此语句由一个表达式组成,该表达式通常仅对其值有用,将被丢弃.仅增加...",现在消息的目的变得更加清晰.

C#中有很多错误消息令人困惑.例如,考虑我个人的最爱:

params参数必须是形式参数列表中的最后一个参数

如果您不知道params参数是如何工作的,那么从这个(params int[] x, params int[] y)合法的错误消息中得出结论是合理的- 毕竟,params参数是形式参数列表中的最后一个参数!结论(int x)是错误的也是明智的,因为params参数不是该列表中的最后一个参数!

当然,我们知道错误消息的含义是" 如果你有一个params参数,那么该参数必须是形式参数列表中的最后一个参数".

错误消息是任何编译器最重要的输出之一,但它们往往令人困惑,不合语法,深奥和无益.这是为什么?

  • 编译器编写者不是英语专业.
  • 编译器错误消息通常是在编译器编写器的便利性的情况下编写的,而不是用户的方便.示例:我花了几周的时间来改进涉及lambdas的问题的重载解析错误消息报告逻辑,以便将LINQ添加到C#3不会使错误消息产生误导.这是很多工作,它花掉了本可以花在其他工作上的努力.
  • 编译器编写者是领域专家,他们发现很难回到"初学者心态".

但最难的是:

  • 为了编写错误信息,编译器编写者必须想象自己处于犯错误的人的精神状态,并找出什么会 以导致正确编写程序的方式消除错误的精神状态.这是人类心理学中的一个难题!编译器编写者不是读者,但他们被要求一直都是.

所以这里发生的是:编译器期待一个声明.它发现expression ;它看起来像一个表达式语句.但是表达式语句中只有一部分表达式是合法的; 如果它不是其中之一,则报告此错误.


如果您对如何改进错误消息有所了解,请不要在此处报告; 开始讨论Roslyn github论坛.


说到:你引用的错误信息是错误的.它被await添加到语言时从未更新过.await x是一种表达,await x;是合法的.