Перечисления, безусловно, могут сделать код более читаемым. Есть еще несколько вещей, на которые следует обратить внимание (по крайней мере, в .net)
Поскольку базовым хранилищем перечисления является int, значение по умолчанию будет равно нулю, поэтому вы должны убедиться, что 0 является разумным значением по умолчанию. (Например, в структурах все поля при создании установлены в ноль, поэтому нет способа указать значение по умолчанию, кроме 0. Если у вас нет значения 0, вы даже не можете протестировать перечисление без преобразования в int, что было бы плохой стиль.)
Если ваше перечисление является частным для вашего кода (никогда не публикуется), вы можете прекратить читать здесь.
Если ваши перечисления опубликованы каким-либо образом во внешнем коде и / или сохраняются вне программы, рассмотрите возможность их явной нумерации. Компилятор автоматически нумерует их от 0, но если вы измените порядок перечислений, не задав им значений, вы можете столкнуться с дефектами.
Я могу легально написать
WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );
Для борьбы с этим любой код, использующий перечисление, в котором вы не можете быть уверены (например, общедоступный API), должен проверять, действительно ли перечисление. Вы делаете это через
if (!Enum.IsDefined(typeof(WriteMode), userValue))
throw new ArgumentException("userValue");
Единственное предостережение в Enum.IsDefined
том, что он использует отражение и работает медленнее. Также существует проблема с версией. Если вам нужно часто проверять значение перечисления, вам будет лучше следующее:
public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
switch( writeMode )
{
case WriteMode.Append:
case WriteMode.OverWrite:
break;
default:
Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
return false;
}
return true;
}
Проблема с версией заключается в том, что старый код может знать только, как обрабатывать 2 перечисления, которые у вас есть. Если вы добавите третье значение, Enum.IsDefined будет истинным, но старый код не обязательно сможет его обработать. Упс.
С [Flags]
перечислениями можно сделать еще больше удовольствия , и код проверки для этого немного отличается.
Я также отмечу, что для переносимости вы должны использовать call ToString()
для enum и использовать Enum.Parse()
при чтении их обратно. Оба ToString()
и Enum.Parse()
могут обрабатывать[Flags]
enum, поэтому нет причин не использовать их. Имейте в виду, это еще одна ловушка, потому что теперь вы не можете даже изменить имя перечисления, возможно, не нарушив код.
Итак, иногда вам нужно взвесить все вышеперечисленное, когда вы спрашиваете себя: « Могу ли я уйти с помощью только bool?»