Енуми, безумовно, можуть зробити код більш читабельним. Є ще кілька речей, на які слід стежити (як мінімум у .net)
Оскільки базовим сховищем enum є 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;
}
Проблема версій полягає в тому, що старий код може знати лише те, як поводитися з двома перерахунками. Якщо ви додасте третє значення, Enum.IsDefined буде істинним, але старий код не обов'язково може обробити його. Уопс.
Ще більше розваг можна зробити із [Flags]
перерахунками, і код перевірки для цього дещо інший.
Я також зазначу, що для портативності вам слід використовувати дзвінок ToString()
на enum та використовувати Enum.Parse()
під час їх читання. І те ToString()
й Enum.Parse()
інше[Flags]
інше enum, тому немає причин не використовувати їх. Майте на увазі, це ще одна помилка, тому що зараз ви навіть не можете змінити назву переліків, не маючи порушення коду.
Отже, іноді вам потрібно зважити все вищесказане, коли ви запитуєте себе: чи можу я піти просто з булом?