Ответ 1
В таком случае я постараюсь не использовать перечисление, а скорее класс с общедоступными статическими полями readonly, которые являются экземплярами класса. Посмотрите, что делает инфраструктура .Net с цветами, например. Существует класс Color, и вы можете использовать такие объекты, как Color.Black, Color.Blue и т.д. Они не являются константами, но предлагают почти все те же преимущества. Кроме того, у них есть другие преимущества, которых нет у констант. См. Спецификацию языка С# версии 3, которая также немного об этом говорит.
Но идея в том, что у вас нет аргумента case. Вы добавляете достаточно других свойств каждому члену "enum", чтобы метод (DoSomething или что-то еще) мог правильно его обработать. Когда другой разработчик хочет добавить еще один объект-член, ему необходимо предоставить необходимые атрибуты. Мой пример: мне понадобилось "перечисление" для различных действий, которые пользователь может принять в системе. Эти действия нужно было проверять на наличие разрешений, регистрироваться и т.д. Мне также нужны действия родителя и ребенка (переименование чего-то является "частью" его редактирования и т.д.), Абстрактные действия, используемые для группировки действий для целей фильтрации, и специальные действия "Все" и "Нет" (None undefined). Каждому требовался идентификатор и текст в базе данных. Я хотел, чтобы он по-прежнему работал, если кто-то изобрел новый тип действия. То, что я сделал, это что-то вроде этого (много кода опущено только для того, чтобы дать вам идею):
public class Action
{
protected Action(bool Abstract, Action Parent, int ID, string Name, bool Undefined)
{ /* snip */ }
protected Action(bool Abstract, Action Parent, int ID, string Name)
: this(Abstract, Parent, ID, Name, false)
{ }
//----------------------------------------------------------------------------------------
public static readonly Action All = new Action(true, null, 0, "All");
public static readonly Action None = new Action(false, All, 6, "(Undefined)", true);
public static readonly Action Modifying = new Action(true, All, 1, "Modifying");
public static readonly Action Creating = new Action(false, Modifying, 2, "Creating");
public static readonly Action Deleting = new Action(false, Modifying, 3, "Deleting");
public static readonly Action Editing = new Action(false, Modifying, 4, "Editing");
public static readonly Action Exporting = new Action(false, All, 5, "Exporting");
public static readonly Action Renaming = new Action(false, Editing, 7, "Renaming");
/* snip */
//----------------------------------------------------------------------------------------
/* template for new entries:
public static readonly Action = new Action(false, All, , "");
*/
}
Есть больше действий. И есть ряд методов в других классах, которые действуют на действия. Они все продолжают работать, пока каждое действие предоставляет необходимую информацию. Разработчик, добавляющий действие, вынужден предоставить информацию. Если текущие атрибуты недостаточны для какого-то будущего "специального" действия, тогда дополнительные атрибуты нужно будет добавить позже. Обратите внимание, что конструкторы защищены, поэтому только сам класс может создавать действия. Я пропустил много кода в главном конструкторе, который проверяет наличие дубликатов идентификаторов и имен и многое другое. Теперь вы можете использовать его следующим образом:
Log.LogAction(Action.Renaming);
В методе LogAction нет аргумента case. Он использует атрибуты действия.
Каково ваше перечисление?
Привет