枚举的加法与减法和强制转换

本文关键字:转换 枚举 | 更新日期: 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))。换句话说,运算符计算xy序数之间的差值,结果的类型是枚举的底层类型。

E operator -(E x, U y);

该操作符的求值与(E)((U)x - y)完全相同。换句话说,操作符从枚举的基础类型中减去一个值,生成该枚举的一个值。

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

我不知道这些操作符中有任何存在,我也从来没有在知情的情况下看到它们被使用。我怀疑它们存在的原因隐藏在Eric Lippert偶尔提到的语言设计会议记录的某个地方——但如果它们因为添加了没有什么好处的特性而感到遗憾,我也不会感到惊讶。不过,也许在某些情况下,它们真的很有用:)

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

有一半的情况下,添加的值太高,不能作为一个有效的enum。

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