Verstehe ich grundsätzlich falsch, wie HasFlags funktioniert? Ich kann nicht verstehen, warum dieser Code versagt.Warum schlägt meine [Flag] -Enum-Validierung fehl?
Dieser Code nimmt einen Wert und bestimmt, ob es eine gültige Kombination von Werten meiner Enum ist.
Zwei Untergruppen von Enum-Werten werden durch ODER-Verknüpfung anderer Elemente identifiziert: JustTheMonths und Exclusives. JustTheMonths ist in der Enum deklariert, und Exclusives ist in der Validierungsmethode enthalten.
Wenn ich 1 oder 2 (Nicht zugeordnet oder Unbekannt) an diese Methode übergebe, identifiziert sie sie korrekt als gültig - Exclusives, aber nicht Mitglieder von JustTheMonths.
Aber wenn ich 4 an diesen Code übergeben, identifiziert es es korrekt als Mitglied des gesamten Satzes, aber identifiziert es falsch als ein Mitglied der Untergruppe JustTheMonths.
Was mache ich hier falsch? Warum denkt mein Code, dass 4 ein Mitglied von (8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8172 | 16344) ist?
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;
}
Von https://msdn.microsoft.com/en-us/library/system.enum(v=vs.110).aspx: . . Definieren Sie Aufzählungskonstanten in Zweierpotenzen, dh 1, 2, 4, 8 und so weiter. Dies bedeutet, dass die einzelnen Flags in kombinierten Aufzählungskonstanten nicht überlappen. –
@ m-y Ähm, nein. Der Compiler ordnet '0, 1, 2, 3, 4, ...' in Abwesenheit von expliziten Werten zu. Das Attribut "Flags" ändert dieses Verhalten nicht. –
@KennethK .: Ich stehe korrigiert, du hast Recht. –