枚举的加法与减法和强制转换
本文关键字:转换 枚举 | 更新日期: 2023-09-27 18:03:55
为什么加法需要强制转换,而减法不需要强制转换?请看下面的代码来理解我在问什么
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#语言规范支持——在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))
。换句话说,运算符计算x
和y
序数之间的差值,结果的类型是枚举的底层类型。E operator -(E x, U y);
该操作符的求值与
(E)((U)x - y)
完全相同。换句话说,操作符从枚举的基础类型中减去一个值,生成该枚举的一个值。
所以这就是为什么编译器的行为是这样的-因为这是c#规范所说的:)
我不知道这些操作符中有任何存在,我也从来没有在知情的情况下看到它们被使用。我怀疑它们存在的原因隐藏在Eric Lippert偶尔提到的语言设计会议记录的某个地方——但如果它们因为添加了没有什么好处的特性而感到遗憾,我也不会感到惊讶。不过,也许在某些情况下,它们真的很有用:)
枚举的默认值为0,1,2…因此,在这种情况下,两个枚举之间的差将创建另一个枚举(首先比较它们以确保您从较大的中减去较小的)。
有一半的情况下,添加的值太高,不能作为一个有效的enum。
问题是这个上下文中的"+"不像枚举值之间的加号。重要的是要理解+是操作符,并且没有规则定义如何将其应用于操作数(Stuff)。A and Stuff.B)