【问题标题】:Enum addition vs subtraction and casting枚举加法与减法和强制转换
【发布时间】:2011-07-30 09:09:27
【问题描述】:

为什么加法需要强制转换但减法不需要强制转换?请参阅下面的代码以了解我的要求

public enum Stuff
{
    A = 1,
    B = 2,
    C = 3
}

var resultSub = Stuff.A - Stuff.B; // Compiles
var resultAdd = Stuff.A + Stuff.B; // Does not compile
var resultAdd2 = (int)Stuff.A + Stuff.B; // Compiles     

注意:对于加法和减法,在上述所有三个示例中,结果是否超出(枚举的)范围都没有关系。

【问题讨论】:

  • 我想选择“因为枚举的算术规则是奇怪的”,但我想我会等着看是否有人想出一个真正的解释。
  • 你能告诉我们它在不编译时给你的错误吗?

标签: c# .net .net-4.0 enums


【解决方案1】:

好问题 - 我很惊讶第一行和第三行有效。

但是,C# 语言规范支持 - 在第 7.8.4 节中,它谈到了枚举添加:

每个枚举类型都隐式提供以下预定义运算符,其中 E 是枚举类型,U 是 E 的底层类型:

E operator +(E x, U y)
E operator +(U x, E y)

在运行时,这些运算符被精确地计算为 (E)((U)x + (U)y)

在第 7.8.5 节中:

每个枚举类型都隐式提供以下预定义运算符,其中 E 是枚举类型,U 是 E 的底层类型:

U operator -(E x, E y)

该运算符的计算结果与(U)((U)x - (U)y)) 完全相同。也就是说,运算符计算xy的序数值之差,结果的类型是枚举的底层类型。

E operator -(E x, U y);

此运算符的计算结果与(E)((U)x - y) 完全相同。换句话说,运算符从枚举的基础类型中减去一个值,从而产生一个枚举值。

这就是为什么编译器会这样 - 因为这是 C# 规范所说的 :)

我不知道存在任何这些运算符,而且我从未故意看到它们被使用过。我怀疑它们存在的原因隐藏在 Eric Lippert 偶尔深入研究的语言设计会议笔记中的某个地方 - 但如果他们因为添加功能没有什么好处而感到遗憾,我也不会感到惊讶。再说一次,也许它们在某些情况下真的很有用:)

【讨论】:

    【解决方案2】:

    枚举的默认值为 0,1,2...所以在这种情况下,两个枚举之间的差异将创建另一个枚举(首先比较它们以确保您从较大的值中减去较小的值)。

    一半的时间加法会创建一个太高而不能成为有效枚举的值。

    【讨论】:

      【解决方案3】:

      问题是这个上下文中的“+”不像枚举值之间的加号。 重要的是要了解 + 是运算符,并且没有定义如何将其应用于操作数(Stuff.A 和 Stuff.B)的规则

      【讨论】:

        猜你喜欢
        • 2016-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多