我正在尝试使用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){
}
答案 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)
{
...
}
这样做的好处是只进行一次测试(我还希望编译器在构建期间执行|
,所以这只是“ldc
,and
,{{1 “}或”brtrue
,ldc
,and
“
答案 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))
{
}