Manchmal ist es notwendig dass man die verschiedenen Werte einer Aufzählung zu einem eindeutigen Wert kombinieren kann.
Ein Beispiel dafür sind die Zugriffsrechte auf ein Objekt, sei es eine Datei im Dateisystem oder seien es Daten in einer Datenbank.
Nehmen wir an wir müssen zwischen den folgenden Rechten unterscheiden können:
- Lesen
- Schreiben
- Löschen
Nun können wir entweder verschiedene Eigenschaften wie:
- HasReadRights
- HasWriteRights
- HasDeleteRights
verwenden um jeweils das Lese, Schreib oder Löschrecht für ein Objekt zu hinterlegen, oder eben wir verwenden dazu eine Aufzählung.
public enum ObjectRights { Read = 0x01, Write = 0x02, Delete = 0x04 }
Wenn wir nun ein Objekt zur Speicherung einer solchen Aufzählung definieren können wir darin bereits die kombinierten Werte ablegen, allerdings werden die Werte dann als Integer Ergebnis der Bitweisen Oder Operation abgelegt.
Beispiel:
ObjectRights Rechte = ObjectRights.Read | ObjectRights.Delete;
Ergibt zum Beispiel in der Ausgabe mit:
System.Diagnostics.Debug.WriteLine(Rechte);
folgendes:
5
Das ist das Resultat der Bitweisen Oder Operation 0x01 | 0x04
Um nun aber anstelle der Integer Werte, die Aufzählungstypen als Bitfelder zu interpretieren müssen wir der Aufzählung ein zusätzliches Attribut [Flags] mitgeben. diese geschieht wie nachfolgend abgebildet:
[Flags] public enum ObjectRights { Read = 0x01, Write = 0x02, Delete = 0x04 }
Wenn wir nun die Werte mit dem Bitweise Oder Operator kombinieren werden die Werte wie Bitfelder behandelt.
ObjectRights Rechte = ObjectRights.Read | ObjectRights.Write | ObjectRights.Delete
Die Ausgabe von Rechte mit System.Diagnostics.Debug.WriteLine(Rechte);
ergibt nun:
Read, Delete
Um abzufragen ob ein bestimmtes Recht gesetzt ist, können wir den Bitweise Und Operator verwenden:
if ((Rechte & ObjectRights.Read) == ObjectRights.Read) { System.Diagnostics.Debug.WriteLine("Lesen erlaubt"); } if ((Rechte & ObjectRights.Write) == ObjectRights.Write ) { System.Diagnostics.Debug.WriteLine("Schreiben erlaubt"); } if ((Rechte & ObjectRights.Delete) == ObjectRights.Delete) { System.Diagnostics.Debug.WriteLine("Löschen erlaubt"); }
Danke für den Beitrag, ist gut erklärt und Enum Flags sind ja äußerst nützlich. Allerdings ist das Übergeben einer Kombination von Flags durchaus umständlich, wenn man das ganze als Konstruktor- oder Funktionsparameter zulässt. Bei mehr als zwei Flags sieht es doch arg schlimm aus.
Täusche ich mich oder kommt bei dem Beispiel
ObjectRights Rechte = ObjectRights.Read | ObjectRights.Write | ObjectRights.Delete
als Ergebnis bei der Ausgabe nicht Read, Write, Delete raus?