C# 枚举和减法运算符

C# 枚举和减法运算符,c#,enums,C#,Enums,有人知道(可能是:从何时起)枚举值支持-=运算符吗 今天我正在愉快地编写代码,出于某种原因,我写了这篇文章以从flagsenum中排除一个值: flags -= FlagsEnum.Value1; 在重新阅读和评估了我的代码之后,我惊讶地发现编译后的代码居然有效 将声明写为 flags = flags - FlagsEnum.Value1 但是,不会编译 到目前为止,我在文档和互联网上都找不到任何东西。此外,不支持其他运算符(当然,位运算符除外):+=(包括标志),*=(Pascal中的交集

有人知道(可能是:从何时起)枚举值支持
-=
运算符吗

今天我正在愉快地编写代码,出于某种原因,我写了这篇文章以从flags
enum
中排除一个值:

flags -= FlagsEnum.Value1;
在重新阅读和评估了我的代码之后,我惊讶地发现编译后的代码居然有效

将声明写为

flags = flags - FlagsEnum.Value1
但是,不会编译

到目前为止,我在文档和互联网上都找不到任何东西。此外,不支持其他运算符(当然,位运算符除外):
+=
(包括标志),
*=
(Pascal中的交集)不起作用

这是C#编译器内置的一些语法糖吗?若有,为何选择不包括其他营办商?

一个简单的代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4
{
    [Flags]
    enum FlagsEnum
    {
        None = 0,
        Value1 = 1,
        Value2 = 2,
        Value3 = 4
    }

    class Program
    {
        static void Main(string[] args)
        {
            FlagsEnum flags = FlagsEnum.Value1 | FlagsEnum.Value2 | FlagsEnum.Value3;
            Console.WriteLine(flags);
            flags -= FlagsEnum.Value1;
            Console.WriteLine(flags);
            flags -= FlagsEnum.Value3;
            Console.WriteLine(flags);
            flags -= FlagsEnum.Value2;
            Console.WriteLine(flags);
            Console.ReadLine();
        }
    }
}

枚举减法。每个枚举类型都隐式提供以下预定义运算符,其中E是枚举类型,U是E的基础类型: U运算符–(ex,ey); 此运算符的求值方式为(U)((U)x–(U)y)。换句话说,运算符计算x和y的序数值之间的差值,结果的类型是枚举的基础类型


我希望您知道,您可以为enum成员定义隐式值,因此如果您给它们值x=5,y=10,z=15,然后尝试执行z-y,您将得到x

Iirc,
-
仍然是整数减法

要执行您想要的操作,请执行以下操作:

value = value & ~SomeEnum.Flag;
包括:

value = value | SomeEnum.Flag;
同样,要测试部分匹配(来自标志的任何位):

或完全匹配(标志中的所有位):


你确定它真的有效吗?你可能会被这样一个事实所欺骗:减法似乎排除了位。您是否在与Value1对应的位已经为0的flags变量上尝试过它?这样使用它是非常不安全的。只有当
FlagsEnum.Value1
已经在
flags
@Jaroslav中时,它才会作为enum工作。我从来没有这样做过,但它只是碰巧从我的手指中滚出来。我把它归咎于Delphi(它有很好的集合操作符),但我对它的编译感到相当(尽管现在不那么)惊讶。正如马克指出的,结果可能不是你所期望的。谁否决了这一点<代码>&(~flag)是删除标志的正确方法,
|(flag)
是添加标志的正确方法,
&
是交叉点的正确方法。是的,这是“正常”方法。这就是我的问题。@Marc:我知道枚举是如何工作的。这就是为什么我一开始就问这个问题。@Willem-ou没有领会我的意思;你声称“它有效”;规范说这是整数子动作。这不是你想删除的(问题)。所以在我看来,这不符合你的想法(问题)。@Willem-底层类型可能是short/byte吗?如果是这样,它们的-始终返回int,因此需要额外的强制转换才能返回到基础类型;-=具有特殊处理,不需要castAaah…规格:唯一一个我没有看的地方(老实说,几乎从来没有看)。谢谢你知道为什么没有用类似的方式为枚举定义+=运算符吗?这两种方法都有效,但当你写E-=E时,它已经被强制转换为E,当你试图用E=E-E的方式来做时,你应该使用隐式强制转换E=(MyEnum)(E-E)
if((value & SomeEnum.Flag) != 0) {...}
if((value & SomeEnum.Flag) == SomeEnum.Flag) {...}