为什么我的[Flag] Enum验证失败了?

时间:2016-09-27 00:35:40

标签: c# validation enums bitflags

我是否从根本上误解了HasFlags的工作原理?我无法理解为什么这段代码失败了。

此代码采用一个值并确定它是否是我的枚举值的有效组合。

两个Enum值子组由ORing其他成员识别:JustTheMonths和Exclusives。 JustTheMonths在Enum中声明,而Exclusives是在验证方法中构建的。

当我将1或2(未分配或未知)传递给此方法时,它正确地将它们识别为有效 - 独占,但不是JustTheMonths的成员。

但是当我将4传递给此代码时,它正确地将其识别为整个集合的成员,但错误地将其识别为子组JustTheMonths的成员。

我在这里做错了什么?为什么我的代码认为4是(8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8172 | 16344)的成员?

    private void Form1_Load(object sender, EventArgs e)
    {
        FloweringMonth test = FloweringMonth.NotApplicable;

        if (IsValidFloweringMonthValue((int)test))
        {
            System.Diagnostics.Debug.WriteLine("Valid");
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("Not Valid");
        }
    }

    [Flags]
    public enum FloweringMonth
    {
        Unassigned = 1, Unknown = 2, NotApplicable = 4,
        Jan = 8, Feb = 16, Mar = 32, Apr = 64, May = 128, Jun = 256,
        Jul = 512, Aug = 1024, Sep = 2048, Oct = 4086, Nov = 8172, Dec = 16344,
        JustMonths = (Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec)
    }

    public static bool IsValidFloweringMonthValue(int value)
    {
        FloweringMonth incoming = (FloweringMonth)value;

        FloweringMonth AllVals = FloweringMonth.Unassigned | FloweringMonth.Unknown |
            FloweringMonth.NotApplicable | FloweringMonth.Jan | FloweringMonth.Feb | 
            FloweringMonth.Mar | FloweringMonth.Apr | FloweringMonth.May | 
            FloweringMonth.Jun | FloweringMonth.Jul |  FloweringMonth.Aug | 
            FloweringMonth.Sep | FloweringMonth.Oct | FloweringMonth.Nov | FloweringMonth.Dec;

        // does the incoming value contain any enum values from AllVals?
        bool HasMembersOfAll = AllVals.HasFlag(incoming);
        if (!HasMembersOfAll) return false;

        // does the incoming value contain any enum values from JustTheMonths?
        bool HasMembersOfMonths = FloweringMonth.JustMonths.HasFlag(incoming);

        // does it contain any enum values from the set of three exclusive values?
        FloweringMonth Exclusives = (FloweringMonth.Unassigned | 
            FloweringMonth.Unknown | FloweringMonth.NotApplicable);
        bool HasMembersOfExclusives = Exclusives.HasFlag(incoming);

        // an exclusive value cannot be mixed with any month values
        if (HasMembersOfMonths && HasMembersOfExclusives) return false;  // bad combo

        // an exclusive value cannot be mixed with other exclusive values
        if (incoming.HasFlag(FloweringMonth.Unassigned) && 
            incoming.HasFlag(FloweringMonth.Unknown)) return false;
        if (incoming.HasFlag(FloweringMonth.Unassigned) && 
            incoming.HasFlag(FloweringMonth.NotApplicable)) return false;
        if (incoming.HasFlag(FloweringMonth.Unknown) && 
            incoming.HasFlag(FloweringMonth.NotApplicable)) return false;

        return true;
    }

2 个答案:

答案 0 :(得分:2)

您的2的倍数不正确。 4086应为40968172应为8192,等等......

答案 1 :(得分:2)

在@dukedukes回答之后,问题是您的2的倍数已经关闭。

避免此错误的一种方法是在右侧使用bitwise操作。

[Flags]
enum Months
{
    January = 1 << 3, // 8
    February = 1 << 4, // 16
    March = 1 << 5, // 32
}