枚举flagsattribute

时间:2012-05-01 08:17:04

标签: c# enums bit-manipulation

我正在尝试使用FlagsAttribute评估枚举,如下所示。问题在于确保正确的 if 语句运行所需的代码数量过多。我有四个 if 语句,只有在设置枚举的特定组合但没有其他时才会执行:

  1. 私人,静态
  2. 私人
  3. 特权
  4. 公共
  5. 检测所需标志的存在很容易,但我还必须确保设置其他标志,这是一个非常多的类型的代码,看起来像维护噩梦。

    [Flags]
    public enum AccessModifierType : short
    {
        Infer = 1,
        Public = 2,
        Privileged = 4,
        Private = 8,
        Static = 16
    }
    

    任何人都可以重写这个 if 语句更简洁吗?

    if ((Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Public) == AccessModifierType.Public
            && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Static) != AccessModifierType.Static
            && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Privileged) != AccessModifierType.Privileged
            && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Private) != AccessModifierType.Private){
    }
    

4 个答案:

答案 0 :(得分:2)

目前尚不清楚您的最终样本与原始需求的关系(我感觉Infer有一些特殊含义?)但是如果您正在寻找特定的位组合除此之外,为什么不对正确的预期枚举值使用相等测试(通过按位OR组合)?

if(myUnknownFlagsEnumValue == (MyEnum.RequiredFlag1 | MyEnum.RequiredFlag2))
{
    ...
}

答案 1 :(得分:1)

首先,比较0更容易,就像提升您重复使用的值一样:

var access = Model.CurrentContext.CurrentAccessModifierType;
if ((access & AccessModifierType.Public) != 0
    && (access & AccessModifierType.Static) == 0
    && (access & AccessModifierType.Privileged) == 0
    && (access & AccessModifierType.Private) == 0)
{
    ...
}

如果你想测试而没有其他标志,那么只需:

if (Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Public)
{
    ...
}

如果你希望它是公开的,而不是其他三个?然后大概是:

if(Model.CurrentContext.CurrentAccessModifierType & (
     AccessModifierType.Public | AccessModifierType.Static |
     AccessModifierType.Priveleged | AccessModifierType.Private
    ) ==  AccessModifierType.Public)
{
   ...
}

这样做的好处是只进行一次测试(我还希望编译器在构建期间执行|,所以这只是“ldcand,{{1 “}或”brtrueldcand

答案 2 :(得分:0)

当然要测试是否只设置了一个标志,你只需要测试该标志:

if( Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Private)
...

要查看它是否等于标志的确切组合,请再次测试该组合:

if( Model.CurrentContext.CurrentAccessModifierType == (AccessModifierType.Private & AccessModifierType.Static))
...

要理解这一点,请记住枚举实际上只是一个数字。因此,如果您的枚举值为Private,则它仅存储为8,因此只需测试它是否等于8(或私有)。如果它是私有和静态那么它是8 + 16 = 24.所以要测试它是否都是那些然后只测试它是否等于24(或私有和静态)。

答案 3 :(得分:0)

如果您使用某些扩展方法 - 示例here,那么您应该能够简化代码。

AccessModifierType modifier = Model.CurrentContext.CurrentAccessModifierType;
if (modifier.Has(AccessModifierType.Public) && 
    modifier.Has(AccessModifierType.Static) &&
    modifier.Has(AccessModifierType.Privileged) && 
    modifier.Has(AccessModifierType.Private))
{
}