Die in .NET integrierten Flag-Enum-Operationen sind leider recht begrenzt. Meistens müssen Benutzer die bitweise Operationslogik herausfinden.
In .NET 4 wurde die Methode HasFlag
hinzugefügt, Enum
die den Benutzercode vereinfacht, aber leider gibt es viele Probleme damit.
HasFlag
ist nicht typsicher, da es jede Art von Aufzählungswertargument akzeptiert, nicht nur den angegebenen Aufzählungstyp.
HasFlag
ist nicht eindeutig, ob geprüft wird, ob der Wert alle oder einige der vom Argument enum value bereitgestellten Flags enthält. Es ist übrigens alles.
HasFlag
ist ziemlich langsam, da es Boxen erfordert, was Zuordnungen und damit mehr Speicherbereinigungen verursacht.
Zum Teil aufgrund der eingeschränkten Unterstützung von .NET für Flag-Enums habe ich die OSS-Bibliothek Enums.NET geschrieben die jedes dieser Probleme behebt und den Umgang mit Flaggenaufzählungen erheblich erleichtert.
Im Folgenden sind einige der Vorgänge aufgeführt, die zusammen mit den entsprechenden Implementierungen nur mit dem .NET-Framework bereitgestellt werden.
Flaggen kombinieren
.NETZ flags | otherFlags
Enums.NET flags.CombineFlags(otherFlags)
Fahnen entfernen
.NETZ flags & ~otherFlags
Enums.NET flags.RemoveFlags(otherFlags)
Gemeinsame Flaggen
.NETZ flags & otherFlags
Enums.NET flags.CommonFlags(otherFlags)
Flaggen umschalten
.NETZ flags ^ otherFlags
Enums.NET flags.ToggleFlags(otherFlags)
Hat alle Flaggen
.NET (flags & otherFlags) == otherFlags
oderflags.HasFlag(otherFlags)
Enums.NET flags.HasAllFlags(otherFlags)
Hat irgendwelche Flaggen
.NETZ (flags & otherFlags) != 0
Enums.NET flags.HasAnyFlags(otherFlags)
Fahnen holen
.NETZ
Enumerable.Range(0, 64)
.Where(bit => ((flags.GetTypeCode() == TypeCode.UInt64 ? (long)(ulong)flags : Convert.ToInt64(flags)) & (1L << bit)) != 0)
.Select(bit => Enum.ToObject(flags.GetType(), 1L << bit))`
Enums.NET flags.GetFlags()
Ich versuche, diese Verbesserungen in .NET Core und möglicherweise in das vollständige .NET Framework zu integrieren. Sie können meinen Vorschlag hier überprüfen .