c#enum exclude

时间:2011-03-21 11:56:32

标签: c# enums

假设我有一个这样的枚举:

[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

3 个答案:

答案 0 :(得分:15)

如果类型列表永远不会改变,您可以这样做:

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为空,则您将无法获得< em>打印为“电子邮件,传真,短信”,而不是“全部”。

如果您不想手动维护allTypes列表,可以使用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);

通过将枚举的所有单个值进行OR运算来构建allType值。

答案 1 :(得分:3)

一个简单的XOR可以解决这个问题......

    NotificationMethodType all = (NotificationMethodType.Email | NotificationMethodType.Fax | NotificationMethodType.Sms);
    NotificationMethodType used = (NotificationMethodType.Email | NotificationMethodType.Fax);
    NotificationMethodType unused = (all ^ used);

为了使它更清洁,直接将All值添加到枚举定义中(显然将值设置为7)。这样,您可以稍后在枚举中添加内容而不会破坏此代码

答案 2 :(得分:0)

var notAssigned = Enum.GetValues(typeof(NotificationMethodType))
                      .Cast<NotificationMethodType>()
                      .Where(x => !types.HasFlag(x))
                      .Aggregate((a, x) => a | x);