Ось приклад, коли прапори корисні.
У мене є фрагмент коду, який генерує паролі (використовуючи криптографічно захищений генератор псевдовипадкових чисел). Абонент методу вибирає, чи повинен пароль містити великі літери, малі літери, цифри, основні символи, розширені символи, грецькі символи, кирилицю та унікод.
За допомогою прапорів назвати цей метод легко:
var password = this.PasswordGenerator.Generate(
CharacterSet.Digits | CharacterSet.LowercaseLetters | CharacterSet.UppercaseLetters);
і навіть його можна спростити:
var password = this.PasswordGenerator.Generate(CharacterSet.LettersAndDigits);
Без прапорців, який би був підпис методу?
public byte[] Generate(
bool uppercaseLetters, bool lowercaseLetters, bool digits, bool basicSymbols,
bool extendedSymbols, bool greekLetters, bool cyrillicLetters, bool unicode);
називається так:
// 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);
Як зазначається в коментарях, іншим підходом було б використання колекції:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LowercaseLetters,
CharacterSet.UppercaseLetters,
});
Це набагато читабельніше порівняно з набором true
та false
, але все ж має два недоліки:
Основним недоліком є те, що для того, щоб дозволити комбіновані значення, CharacterSet.LettersAndDigits
ви , наприклад , пишете щось подібне у Generate()
методі:
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.
}
можливо переписати так:
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.
}
Порівняйте це з тим, що у вас є, використовуючи прапори:
if (set & CharacterSet.LowercaseLetters == CharacterSet.LowercaseLetters)
{
// The password should contain lowercase letters.
}
Другий, дуже незначний недолік полягає в тому, що незрозуміло, як би поводився метод, якщо його викликали так:
var password = this.PasswordGenerator.Generate(
new []
{
CharacterSet.Digits,
CharacterSet.LettersAndDigits, // So digits are requested two times.
});