c#枚举排除
假设我有这样一个枚举:c#枚举排除,c#,enums,C#,Enums,假设我有这样一个枚举: [Flags] public enum NotificationMethodType { Email = 1, Fax = 2, Sms = 4 } 假设我有一个变量定义为: NotificationMethodType types = (NotificationMethodType.Email | NotificationMethodType.Fax) 如何计算“types”变量中未定义的所有NotificationMethodType值?换
[Flags]
public enum NotificationMethodType {
Email = 1,
Fax = 2,
Sms = 4
}
假设我有一个变量定义为:
NotificationMethodType types = (NotificationMethodType.Email | NotificationMethodType.Fax)
如何计算“types”变量中未定义的所有NotificationMethodType值?换言之:
NotificationMethodType notAssigned = NotificationMethodType <that are not> types
NotificationMethodType notAssigned=NotificationMethodType类型
如果类型列表从未更改,您可以执行以下操作:
NotificationMethodType allTypes = NotificationMethodType.Email |
NotificationMethodType.Fax |
NotificationMethodType.Sms;
NotificationMethodType notAssigned = allTypes & ~types;
~通过反转所有位来创建一个反数值
定义此类枚举以使“allTypes”的定义至少保持在枚举本地的一种典型方法是在枚举中包含两个新名称:
[Flags]
public enum NotificationMethodType {
None = 0,
Email = 1,
Fax = 2,
Sms = 4,
All = Email | Fax | Sms
}
注意:如果您选择将All
值添加到枚举中,请注意,如果types
为空,则不会得到打印为“Email、Fax、Sms”的枚举,而是打印为“All”
如果不想手动维护所有类型的列表
,可以使用Enum.GetValues
方法:
NotificationMethodType allTypes = 0;
foreach (NotificationMethodType type in Enum.GetValues(typeof(NotificationMethodType)))
allTypes |= type;
也可以对LINQ执行相同的操作:
NotificationMethodType allTypes =
Enum.GetValues(typeof(NotificationMethodType))
.Cast<NotificationMethodType>()
.Aggregate ((current, value) => current | value);
NotificationMethodType所有类型=
Enum.GetValues(typeof(NotificationMethodType))
.Cast()
.聚合((当前值)=>当前值);
这将通过将枚举的所有单个值组合在一起来构建
allType
值。一个简单的异或将完成此任务
NotificationMethodType all = (NotificationMethodType.Email | NotificationMethodType.Fax | NotificationMethodType.Sms);
NotificationMethodType used = (NotificationMethodType.Email | NotificationMethodType.Fax);
NotificationMethodType unused = (all ^ used);
要使其更清晰,请直接将All值添加到枚举定义中(将值设置为7)。这样,您就可以在以后向枚举添加内容,而无需中断此代码var notAssigned=enum.GetValues(typeof(NotificationMethodType))
var notAssigned = Enum.GetValues(typeof(NotificationMethodType))
.Cast<NotificationMethodType>()
.Where(x => !types.HasFlag(x))
.Aggregate((a, x) => a | x);
.Cast()
.Where(x=>!types.HasFlag(x))
.骨料((a,x)=>a | x);
fwiw、XOR(运算符)和Lasse的“and not”答案在数学上是相同的。way的效率可能低于使用按位运算的两个答案中的任何一个operators@Robert:我不能否认它的效率较低,但它的适用性实际上取决于OP需要什么。您自己的答案需要一个单独的all
值与主枚举保持同步-如果该枚举发生更改,这将是维护的噩梦!(依我看,这更像是一个缺点,而不是一个在大多数情况下可能永远不会被注意到的假定的效率问题。我显然没有你那么自由和容易地投反对票。)同意,所有这些都应该被定义为枚举的一部分