枚举标志属性



我正在尝试评估应用了 FlagsAttribute 的枚举,如下所示。问题在于它为确保正确的 if 语句运行而花费的代码量非常大。我有四个 if 语句,只有在设置了枚举的特定组合时才应执行,但没有其他内容

  1. 私有、静态
  2. 私人
  3. 特权
  4. 公共

检测所需标志的存在很容易,但我还必须确保没有设置其他标志,这是要键入的代码量非常可笑,看起来像是维护噩梦。

[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){
}

目前尚不清楚您的最终样本与您的原始要求有何关系(我感觉Infer有一些特殊含义?)但是如果您正在寻找特定的位组合而不是其他内容,为什么不直接针对确切的预期枚举值(通过按位 OR 组装)使用相等性测试?

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

首先,与 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)
{
   ...
}

这有一个优点是只有一个测试(我也希望编译器在构建过程中执行|,所以这只是"ldcandbrtrue"或"ldcandbrfalse"

当然,要测试是否只设置了一个标志,您只需针对该标志进行测试:

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

要查看它是否等于标志的精确组合,请再次针对该组合进行测试:

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

为了解决这个问题,请记住枚举实际上只是一个数字。因此,如果您的枚举的值为 Private ,则它只是存储为 8,因此只需测试它是否等于 8(或 Private)。如果它是私有和静态的,那么它是 8 + 16 = 24。因此,要测试它是否是这两个,那么只需测试它是否eqaul 到24(或私有和静态)。

如果你使用一些扩展方法 - 这里的例子,那么你应该能够简化你的代码。

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

最新更新