我有一个标有[Flags]属性的Enum,如下所示:
[Flags]
public enum Tag : int
{
None = 0,
PrimaryNav = 1,
HideChildPages = 2,
HomePage = 4,
FooterLink = 8
}
在我的站点地图中的站点地图节点上,我将标签组合的int值存储为属性。
我需要做的是检查一个节点是否有一个或多个标签的 任何一个 ,例如Tag.PrimaryNav | Tag.HomePage。
我正在努力使用必要的布尔逻辑来确定Enum值是否具有与其进行比较的一个或多个值。
如果不清楚,请道歉。如有必要,我可以提供更多信息。
答案 0 :(得分:27)
您可以将值与|
组合并通过&
进行检查。
要检查该值是否包含 标记:
if ((myValue & (Tag.PrimaryNav | Tag.HomePage)) != 0) { ... }
|
通过按位屏蔽结合您正在测试的枚举(按位)和&
测试 - 如果结果不为零,则至少设置其中一个。< / p>
如果你想测试它们是否设置了两个,你也可以这样做:
Tag desiredValue = Tag.PrimaryNav | Tag.HomePage;
if ((myValue & desiredValue) == desiredValue) { ... }
这里我们掩盖了我们不关心的任何事情,并测试结果值等于我们做关心的事情(我们不能像之前那样使用!= 0
因为这将匹配 值,这里我们对两者感兴趣。
一些链接:
答案 1 :(得分:9)
您可以使用HasFlag方法来避免使用布尔逻辑
Tag Val = (Tag)9;
if (Val.HasFlag(Tag.PrimaryNav))
{
Console.WriteLine("Primary Nav");
}
if(Val.HasFlag(Tag.HomePage))
{
Console.WriteLine("Home Page");
}
答案 2 :(得分:2)
对于按位(Flags
)枚举,“any of”测试是!= 0,所以:
const Tag flagsToLookFor = Tag.PrimaryNav | Tag.HomePage;
if ((node.Tag & flagsToLookFor) != 0) {
// has some cross-over with PrimaryNav or HomePage (and possibly others too)
}
答案 3 :(得分:1)
var someEnumValue = Tag.PrimaryNav | Tag.HomePage;
测试枚举是否包含给定值:
if ((someEnumValue & Tag.PrimaryNav) == Tag.PrimaryNav)
{
}
答案 4 :(得分:1)
var tag = Tag.HideChildPages | Tag.PrimaryNav;
If ((tag & Tag.PrimaryNav) == Tag.PrimaryNav) {
// Tag.PrimaryNav set.
}
答案 5 :(得分:1)
您可以使用Jon Skeet的Unconstrained Melody库:
var someEnumValue = Tag.PrimaryNav | Tag.HideChildPages;
someEnumValue.HasAny(Tag.PrimaryNav | Tag.HomePage); // Returns true
答案 6 :(得分:1)
对于任何类型的枚举,您都可以在枚举上使用此扩展方法:
public static bool IsSingle(this Enum value)
{
var items = Enum.GetValues(value.GetType());
var counter = 0;
foreach (var item in items)
{
if (value.HasFlag((Enum)item))
{
counter++;
}
if (counter > 1)
{
return false;
}
}
return true;
}
答案 7 :(得分:0)
这是经典的扩展方法:
public static bool HasFlag(this Enum val, Enum t)
{
return (Convert.ToUInt64(val) & Convert.ToUInt64(t)) != 0;
}