【问题标题】:Why isn't the C# compiler able to cast a literal negative value to an enum?为什么 C# 编译器不能将文字负值强制转换为枚举?
【发布时间】:2016-08-23 02:24:33
【问题描述】:

这段代码不能用latest C# compiler编译:

public class Program
{
    public static void Main()
    {
        IntEnum a = (IntEnum)-1;
    }
}

public enum IntEnum : int { }

当你尝试编译它时,它会引发

(3,22,3,29):错误 CS0119:“IntEnum”是一种类型,在给定的上下文中无效

奇怪的是,将转换后的值更改为正数(例如 4),或使用 const 值(例如 int.MinValue),甚至用括号括起来像 (IntEnum)(-1) 将编译和工作美好的。但是,上面的示例没有。

这有什么原因吗? Roslyn 是否可能错误地解析了代码,这就是引发错误的原因?

【问题讨论】:

  • @Alexei:谢谢。所以“设计”,因为IntEnum 是用户定义的标识符,而不是预定义的类型。 (请记住,这是旧规范,显然是旧错误代码......但同样的事情也可能适用于 C# 6)。看来这对 C# 6 来说也不是什么新鲜事。
  • @PeterDuniho 我已将评论转换为答案,因为它记录在完全不同的错误中。
  • @AlexeiLevenkov:是的,我明白了。请注意,C# 6 编译器不会发出“完全不同的错误”,恕我直言,这是一个错误。错误消息并没有比“要强制转换负值,您必须将值括在括号中”更好。遗憾的是新编译器没有显示消息。

标签: c# .net enums casting roslyn


【解决方案1】:

预期行为并记录在案以允许解析 (Var)-1 等表达式。

Compiler Error CS0075 进入规范细节(我希望你得到那个错误而不是/除了 CS0119):

要转换负值,必须将值括在括号中 如果您使用标识预定义类型的关键字进行强制转换,则不需要括号。否则,您必须加上括号,因为 (x) –y 不会被视为强制转换表达式。来自 C# 规范,第 7.6.6 节:

根据消歧规则,如果 x 和 y 是标识符,则 (x)y、(x)(y) 和 (x)(-y) 是强制转换表达式,但 (x) -y 不是,即使 x 标识了一个类型。但是,如果 x 是标识预定义类型(例如 int)的关键字,则所有四种形式都是强制转换表达式(因为这样的关键字本身不可能是表达式)。

【讨论】:

  • 注意到这对 C# 6 编译器来说并不新鲜,我确实看到一个显着的区别是在 C# 5 中,错误包括 CS0075,它明确地解释了问题,而该错误或等效not 在 C# 6 中显示。恕我直言,这部分实际上是一个错误,因为它是旧编译器的回归。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 1970-01-01
  • 2016-10-19
相关资源
最近更新 更多