Hier ist ein Beispiel, wenn Flags nützlich sind.
Ich habe einen Code, der Passwörter generiert (unter Verwendung eines kryptografisch sicheren Pseudozufallszahlengenerators). Der Aufrufer der Methode entscheidet, ob das Passwort Großbuchstaben, Kleinbuchstaben, Ziffern, Grundsymbole, erweiterte Symbole, griechische Symbole, kyrillische Symbole und Unicode enthalten soll oder nicht.
Mit Flags ist das Aufrufen dieser Methode einfach:
var password = this.PasswordGenerator.Generate(
CharacterSet.Digits | CharacterSet.LowercaseLetters | CharacterSet.UppercaseLetters);
und es kann sogar vereinfacht werden:
var password = this.PasswordGenerator.Generate(CharacterSet.LettersAndDigits);
Was wäre die Methodensignatur ohne Flags?
public byte[] Generate(
bool uppercaseLetters, bool lowercaseLetters, bool digits, bool basicSymbols,
bool extendedSymbols, bool greekLetters, bool cyrillicLetters, bool unicode);
so genannt:
// Very readable, isn't it?
// Tell me just by looking at this code what symbols do I want to be included?
var password = this.PasswordGenerator.Generate(
true, true, true, false, false, false, false, false);
Wie in den Kommentaren erwähnt, besteht ein anderer Ansatz darin, eine Sammlung zu verwenden:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LowercaseLetters,
CharacterSet.UppercaseLetters,
});
Dies ist im Vergleich zum Satz von true
und viel besser lesbar false
, weist jedoch immer noch zwei Nachteile auf:
Der Hauptnachteil ist, dass Sie, um kombinierte Werte zuzulassen, so CharacterSet.LettersAndDigits
etwas wie das in Generate()
Methode schreiben würden :
if (set.Contains(CharacterSet.LowercaseLetters) ||
set.Contains(CharacterSet.Letters) ||
set.Contains(CharacterSet.LettersAndDigits) ||
set.Contains(CharacterSet.Default) ||
set.Contains(CharacterSet.All))
{
// The password should contain lowercase letters.
}
möglicherweise so umgeschrieben:
var lowercaseGroups = new []
{
CharacterSet.LowercaseLetters,
CharacterSet.Letters,
CharacterSet.LettersAndDigits,
CharacterSet.Default,
CharacterSet.All,
};
if (lowercaseGroups.Any(s => set.Contains(s)))
{
// The password should contain lowercase letters.
}
Vergleichen Sie dies mit dem, was Sie haben, indem Sie Flags verwenden:
if (set & CharacterSet.LowercaseLetters == CharacterSet.LowercaseLetters)
{
// The password should contain lowercase letters.
}
Der zweite, sehr kleine Nachteil ist, dass nicht klar ist, wie sich die Methode verhalten würde, wenn sie wie folgt aufgerufen würde:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LettersAndDigits, // So digits are requested two times.
});