Voici un exemple où les drapeaux sont utiles.
J'ai un morceau de code qui génère des mots de passe (en utilisant un générateur de nombres pseudo-aléatoires cryptographiquement sécurisé). L'appelant de la méthode choisit si le mot de passe doit contenir des lettres majuscules, des lettres minuscules, des chiffres, des symboles de base, des symboles étendus, des symboles grecs, des caractères cyrilliques et unicode.
Avec les drapeaux, appeler cette méthode est simple:
var password = this.PasswordGenerator.Generate(
CharacterSet.Digits | CharacterSet.LowercaseLetters | CharacterSet.UppercaseLetters);
et il peut même être simplifié de:
var password = this.PasswordGenerator.Generate(CharacterSet.LettersAndDigits);
Sans drapeaux, quelle serait la signature de la méthode?
public byte[] Generate(
bool uppercaseLetters, bool lowercaseLetters, bool digits, bool basicSymbols,
bool extendedSymbols, bool greekLetters, bool cyrillicLetters, bool unicode);
appelé comme ça:
// 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);
Comme indiqué dans les commentaires, une autre approche consisterait à utiliser une collection:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LowercaseLetters,
CharacterSet.UppercaseLetters,
});
Ceci est beaucoup plus lisible par rapport à true
et false
, mais a toujours deux inconvénients:
L'inconvénient majeur est que pour permettre des valeurs combinées, CharacterSet.LettersAndDigits
vous écrivez quelque chose comme ça dans la Generate()
méthode:
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.
}
éventuellement réécrit comme ceci:
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.
}
Comparez cela avec ce que vous avez en utilisant des drapeaux:
if (set & CharacterSet.LowercaseLetters == CharacterSet.LowercaseLetters)
{
// The password should contain lowercase letters.
}
Le deuxième inconvénient très mineur est qu'il n'est pas clair comment la méthode se comporterait si elle était appelée ainsi:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LettersAndDigits, // So digits are requested two times.
});