应用运算符时的过载分辨率 |到不同类型的枚举

本文关键字:同类型 枚举 运算符 应用 分辨率 | 更新日期: 2023-09-27 17:56:14

在阅读了最近的问题 在另一个枚举声明中允许不同枚举类型之间的操作,但在其他地方不允许,我想出了这个例子:

    enum Alpha : long
    {
        X,
    }
    enum Beta : ulong
    {
        X,
    }
    enum Gamma : long
    {
        X = Alpha.X | Beta.X,   // problem?
    }
    enum Delta : ulong
    {
        X = Alpha.X | Beta.X,   // no problem?
    }

编译结果:Gamma不会编译 (CS0266:无法将类型"ulong"隐式转换为"long"。存在显式转换(您是否缺少强制转换? Delta愉快地编译。

难道不是 C# 语言规范所不期望的吗?

(注意:如果我将要初始化的Alpha的成员更改为负常量,例如-1L,则GammaDelta都不会编译。

应用运算符时的过载分辨率 |到不同类型的枚举

是的,这是意料之中的,它不是特定于枚举的东西。您可以将其简化为:

long a = 1L | 1UL; // Cannot implicitly convert type 'ulong' to 'long'. An explicit conversion exists (are you missing a cast?)
ulong b = 1L | 1UL;

以下引用的 C# 语言规范描述了它发生的原因。

6.1.9 隐式常量表达式转换

隐式常量表达式转换允许以下转换:

· 可以转换 int 类型的常量表达式 (§7.19) 键入 sbyte、byte、short、ushort、uint 或 ulong,前提是值 的常量表达式在目标范围内 类型。

· long 类型的常量表达式可以转换为类型 ulong,前提是常量表达式的值不为负。

6.1.2 隐式数值转换

隐式数字转换包括:

· 从长到浮点数、双精度或十进制。

· 从乌龙到浮点数、双精度或十进制。

换句话说,Alpha.X(如果基础值为正)可以(实际上是!)隐式转换为ulong。但是Alpha.X | Beta.X的结果是ulong,根据规范,它不能隐式转换为long

但是一旦您将要初始化的Alpha.X更改为负常数,例如 -1L ,那么,根据上面的引用,它就不能再隐式转换为 ulong并且编译将失败并显示不同的错误:Operator '|' cannot be applied to operands of type 'long' and 'ulong'

是的,这是意料之中的,没有从 ulong 到任何整型的隐式转换。

一旦你告诉编译器你 long is -ve,你就给了它足够的信息来表达,你不想那样做。

就我个人而言,我会很高兴它对 long | ulong感到不安,但毫无疑问,一些C程序员影响了这个决定。 :(