错误文本是:
只有赋值、调用、递增、递减和新对象表达式可以作为语句使用
您的问题包括断言:
因此,根据这一点,除上述之外的任何内容都不能成为陈述。
不,这是一个错误的结论。
首先,您所做的只是一个坏主意。 不要阅读错误消息来了解该语言的规则。错误消息是为了告诉您不合法的程序出了什么问题。它们并非旨在作为是合法的指南!错误消息的编写假设上下文是您在阅读错误的同时正在查看非法程序。错误信息是一个句子;语言规范长达 800 页,并且包含更多细节。 阅读规范。
第二:一个正确的结论是:根据那个错误信息,没有其他的表达式可以作为陈述。此错误消息仅在预期语句的上下文中使用无效表达式的上下文中产生。
那么下面一行怎么不产生上述错误呢。
Anyclass obj;
该行不是表达式,因此错误消息不适用于它。
您从该错误消息中得出了错误的结论,这证明该错误消息令人困惑,仅出于这个原因,我们就可以争辩它可以更改。例如,我们可以说“表达式语句”而不是“语句”。或者我们可以诊断更大的问题,并报告“此语句包含一个通常仅对其值有用的表达式,该表达式被丢弃。仅递增......”,现在消息的目的变得更加清晰。
C# 中有很多令人困惑的错误消息。例如,考虑一下我个人最喜欢的:
params 参数必须是形参列表中的最后一个参数
如果你不知道 params 参数是如何工作的,那么从这个错误消息中得出(params int[] x, params int[] y) 是合法的结论是合理的——毕竟,params 参数是形式参数列表中的最后一个参数!得出(int x) 错误的结论也是明智的,因为params 参数不是该列表中的最后一个参数!
当然我们知道错误消息的意思是“如果你有一个params参数,那么那个参数必须是形式参数列表中的最后一个”。
错误消息是任何编译器最重要的输出之一,但它们通常令人困惑、不合语法、深奥且无用。这是为什么呢?
- 编译器作者不是英语专业的。
- 编写编译器错误消息时通常考虑到编译器编写者的方便,而不是用户的方便。示例:我花了数周时间改进涉及 lambda 的问题的重载解析错误消息报告逻辑,以便将 LINQ 添加到 C# 3 不会使错误消息产生误导。那是大量的工作,它占用了本可以花在其他工作上的精力。
- 编译器编写者是领域专家,他们发现很难回到“初学者思维”。
但最难的:
- 要编写错误消息,编译器编写者必须想象自己处于犯了错误的人的心理状态,并弄清楚如何消除错误的心理状态 一种导致编写正确程序的方式。这是人类心理学中的一个难题!编译器编写者不是读心者,但他们被要求始终如此。
所以这里发生的是:编译器期待一个语句。它找到了expression ;,它看起来像一个表达式语句。但是表达式语句中只有表达式的子集是合法的;如果不是其中之一,则报告此错误。
如果您对如何改进错误消息有任何想法,请不要在此处报告;在 Roslyn github 论坛上开始讨论。
说到这:你引用的错误信息是错误的。当 await 添加到语言中时,它从未更新过。 await x 是一个表达式,await x; 是合法的。