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 HasFlaghinzugefügt, Enumdie 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.
HasFlagist 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 .