简体   繁体   English

我如何确定一个 Enum 值是否有一个或多个与之比较的值?

[英]How do I determine if an Enum value has one or more of the values it's being compared with?

I've got an Enum marked with the [Flags] attribute as follows:我有一个用 [Flags] 属性标记的枚举,如下所示:

[Flags]
public enum Tag : int
{
    None = 0,
    PrimaryNav = 1,
    HideChildPages = 2,
    HomePage = 4,
    FooterLink = 8
}

On sitemapnodes in my sitemap I store the int value for the tags combination as an attribute.在我的站点地图中的站点地图节点上,我将标签组合的 int 值存储为一个属性。

What I need to do is check if a node has any one of one or more tags, eg Tag.PrimaryNav |我需要做的是检查一个节点是否有一个或多个标签中的任何一个,例如 Tag.PrimaryNav | Tag.HomePage.标签。主页。

I'm struggling with the necessary boolean logic to determine if an Enum value has one or more of the values it's being compared with.我正在努力使用必要的布尔逻辑来确定一个 Enum 值是否具有一个或多个与之比较的值。

Apologies if this isn't clear.如果不清楚,请见谅。 I can provide more information if necessary.如有必要,我可以提供更多信息。

You can do that by combining values with |您可以通过将值与|组合来实现| and checking via & .并通过&检查。

To check if the value contains either of the tags:要检查该值是否包含一标签:

if ((myValue & (Tag.PrimaryNav | Tag.HomePage)) != 0) { ... }

The || combines the enums you're testing (bitwise) and the & tests via bitwise masking -- if the result isn't zero, it has at least one of them set.通过按位掩码组合您正在测试的枚举(按位)和&测试 - 如果结果不为零,则至少设置了其中一个。

If you want to test whether it has both of them set, you can do that as well:如果你想测试它是否同时设置了它们,你也可以这样做:

Tag desiredValue = Tag.PrimaryNav | Tag.HomePage;
if ((myValue & desiredValue) == desiredValue) { ... }

Here we're masking off anything we don't care about, and testing that the resulting value equals what we do care about (we can't use != 0 like before because that would match either value and here we're interested in both ).这里我们屏蔽掉什么,我们不关心,并测试所得到的值等于我们什么,关心(我们不能用!= 0像以前一样,因为那样会匹配任何一个值,在这里我们感兴趣两者)。

Some links:一些链接:

You can use the HasFlag Method to avoid the need for the boolean logic,您可以使用 HasFlag 方法来避免布尔逻辑的需要,

Tag Val = (Tag)9;

if (Val.HasFlag(Tag.PrimaryNav))
{
    Console.WriteLine("Primary Nav");
}

if(Val.HasFlag(Tag.HomePage))
{
    Console.WriteLine("Home Page");
}

For bitwise ( Flags ) enums, an "any of" test is != 0, so:对于按位( 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) 
}
var someEnumValue = Tag.PrimaryNav | Tag.HomePage;

To test if the enum contains a given value:要测试枚举是否包含给定值:

if ((someEnumValue & Tag.PrimaryNav) == Tag.PrimaryNav)
{

}
var tag = Tag.HideChildPages | Tag.PrimaryNav;

If ((tag & Tag.PrimaryNav) == Tag.PrimaryNav) {
    // Tag.PrimaryNav set.
}

You could use Jon Skeet's Unconstrained Melody library:您可以使用 Jon Skeet 的不受约束的旋律库:

var someEnumValue = Tag.PrimaryNav | Tag.HideChildPages;
someEnumValue.HasAny(Tag.PrimaryNav | Tag.HomePage); // Returns true

You can use this extension method on enum, for any type of enums:您可以在枚举上使用此扩展方法,用于任何类型的枚举:

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;
    }

That's a classic Extension method:这是一个经典的扩展​​方法:

    public static bool HasFlag(this Enum val, Enum t)
    {
            return (Convert.ToUInt64(val) & Convert.ToUInt64(t)) != 0;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM