Я в основном неправильно понимаю, как работает HasFlags? Я не понимаю, почему этот код терпит неудачу.Почему моя проверка флажком [Flag] Enum не работает?
Этот код принимает значение и определяет, является ли он действительной комбинацией значений моего Enum.
Две подгруппы значений Enum идентифицируются ORing другими членами: JustTheMonths и Exclusives. JustMonths объявляется в 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;
}
От https://msdn.microsoft.com/en-us/library/system.enum(v=vs.110).aspx: . . Определенные константы перечисления по степеням двух, то есть 1, 2, 4, 8 и т. Д. Это означает, что отдельные флаги в комбинированных константах перечисления не перекрываются. –
@ m-y Um, no. Компилятор присваивает '0, 1, 2, 3, 4, ...' в отсутствие явных значений. Атрибут 'Flags' не изменяет этого поведения. –
@ KennethK .: Я стою исправлен, вы правы. –