我正在尝试评估应用了 FlagsAttribute 的枚举,如下所示。问题在于它为确保正确的 if 语句运行而花费的代码量非常大。我有四个 if 语句,只有在设置了枚举的特定组合时才应执行,但没有其他内容:
- 私有、静态
- 私人
- 特权
- 公共
检测所需标志的存在很容易,但我还必须确保没有设置其他标志,这是要键入的代码量非常可笑,看起来像是维护噩梦。
[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)
{
...
}
这有一个优点是只有一个测试(我也希望编译器在构建过程中执行|
,所以这只是"ldc
,and
,brtrue
"或"ldc
,and
,brfalse
"
当然,要测试是否只设置了一个标志,您只需针对该标志进行测试:
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))
{
}