枚举加法与减法和铸造

时间:2011-07-30 09:09:27

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

为什么添加需要强制转换但减法在没有强制转换的情况下有效?请参阅下面的代码以了解我的要求

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     

注意:对于加法和减法,在上述所有三个例子中,结果是否超出范围(枚举)并不重要。

3 个答案:

答案 0 :(得分:19)

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

但是,他们 支持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偶尔潜入的语言设计会议记录中 - 但是如果他们因为添加功能而没什么好处而感到后悔也不会感到惊讶。然后,也许他们在某些情况下真的有用:)

答案 1 :(得分:0)

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

一半的时间添加会产生一个太高而无法成为有效枚举的值。

答案 2 :(得分:-1)

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