为什么声明没有给出CS0201编译器错误?

时间:2018-05-24 17:15:07

标签: c# oop

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

  

仅分配,调用,增量,减量和新对象   表达式可以用作语句

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

Anyclass obj;

在这里,我们没有任何作业或召唤或增加或减少或新的对象表达。

我知道我错过了一些东西,因为official documentation与此错误相矛盾,声明声明也是一种陈述。

1 个答案:

答案 0 :(得分:17)

错误文字是:

  

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

您的问题包括断言:

  

所以除此之外的任何事情都不能成为一种陈述。

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

首先,你所做的只是一个坏主意。 请勿阅读错误消息以了解该语言的规则。错误消息可以告诉您使用非法律程序的错误。它们并非旨在成为 合法的指南!写入错误消息时假定上下文是您在阅读错误的同时查看非法程序。错误消息是一个句子;语言规范长达800页,具有更多细节。 阅读规范

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

  

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

Anyclass obj;

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

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

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

  

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

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

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

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

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

但最难的是:

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

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

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

说到:您引用的错误消息错误。将await添加到语言时,它从未更新过。 await x是一个表达式,await x;是合法的。