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