2009-02-05 3 views
17

У меня есть существующее перечисление с множеством элементов в нем.Подмножество или подгруппа enum в C#

У меня также есть существующий код, который делает определенные вещи с этим перечислением.

Теперь я хотел бы просмотреть только элементы перечисления подмножества. То, что я ищу, - это способ разделить мой enum на группы. Мне нужно сохранить значение (int) каждого члена, и мне нужно сохранить возможность просмотра всех членов перечисления, если это необходимо.

Единственное, что я могу придумать, это просто создать новое перечисление для каждого подменю, в котором содержатся только те элементы, которые я хочу использовать с тем же именем и значением.

Это работает, но нарушает принцип без повторения.

Я не ожидаю, что у кого-то будет лучшая альтернатива, но я думал, что попрошу на всякий случай, если кто-то попробует меня показать.

Спасибо, как всегда.

+0

Я не думаю, что есть способ сделать то, что вы хотите (это зависит от того, что вы подразумеваете под« представлением »). Но если вы можете описать большую картину, возможно, есть лучший способ достичь своей цели? – colithium

+0

Точка моего перечисления - позволить другим разработчикам выбирать определенное значение, основанное на его имени. Мое перечисление становится слишком большим, и иногда было бы хорошо, если бы разработчики могли видеть только подмножество членов перечисления на основе определенной группировки. Эта группировка фиксирована. –

ответ

2

В конце концов, мне пришлось переписать большую часть кода, но следующий «трюк» была получена:

я громил C# перечислений и используйте статические элементы в обычном классе. Этот класс был сделан в одноэлементный режим и включен в начало приложения.

Конструкторам статических членов разрешено ссылаться на другой статический член как «родительский».

Далее мой метод init использует отражение для прохождения каждого статического члена и индексирует их на основе нескольких свойств. Эти индексы хранятся в хэш-таблицах, которые также являются членами singleton.

Таким образом, я получаю:

единичный объект, который:

  • имеет статические элементы, которые могут быть легко доступны во время разработки.
  • может использоваться во время выполнения для поиска определенных статических элементов (на основе «группы» и других свойств).

Мой метод инициализации проводит справедливую проверку. Если создаются недействительные (например, повторяющиеся) статические члены, вы получаете ошибку во время запуска приложения.

Очевидно, довольно большой взлом, но я вполне доволен этим.

10

Вы можете определить значения, используя перечисление, но затем ссылаться на них с помощью констант в статических классах, чтобы ваши разработчики не сталкивались с большим перечислением. Вы могли бы:

enum MySuperEnumGroup 
{ 
    Group1Item1, 
    Group1Item2, 
    Group1Item3, 

    Group2Item1, 
    Group2Item2, 
    Group2Item3, 

    Group3Item1, 
    Group3Item2, 
    Group3Item3, 
} 

static class MySuperEnumGroup_Group1 
{ 
    public const MySuperEnumGroup Item1 = MySuperEnumGroup.Group1Item1; 
    public const MySuperEnumGroup Item2 = MySuperEnumGroup.Group1Item2; 
    public const MySuperEnumGroup Item3 = MySuperEnumGroup.Group1Item3; 
} 

static class MySuperEnumGroup_Group2 
{ 
    public const MySuperEnumGroup Item1 = MySuperEnumGroup.Group2Item1; 
    public const MySuperEnumGroup Item2 = MySuperEnumGroup.Group2Item2; 
    public const MySuperEnumGroup Item3 = MySuperEnumGroup.Group2Item3; 
} 

//etc. 
+1

Как просмотреть всех членов перечисления? – Mhd

8

Я бы с этим (который работает в VB.NET, по крайней мере)

enum MySuperEnumGroup 
{ 
    Group1Item1, 
    Group1Item2, 
    Group1Item3, 

    Group2Item1, 
    Group2Item2, 
    Group2Item3, 

    Group3Item1, 
    Group3Item2, 
    Group3Item3, 
} 

enum MySubEnumGroup 
{ 
Group2Item1 = MySuperEnumGroup.Group2Item1 
Group3Item1 = MySuperEnumGroup.Group3Item1 
Group3Item3 = MySuperEnumGroup.Group3Item3 
} 

Затем сделать какой-то CType, когда вам нужно.

2

Если перечисления не имеют явные значений, дать им один и использовать флаги, чтобы определить «группировку»:

[Flags] 
enum MySuperEnumGroup 
{ 
    Group1 = 1 << 0, 
    Group2 = 1 << 1, 
    Group3 = 1 << 2, 

    Group1Item1 = 1 << 10 | Group1, 
    Group1Item2 = 1 << 11 | Group1, 
    Group1Item3 = 1 << 12 | Group1, 

    Group2Item1 = 1 << 13 | Group2, 
    Group2Item2 = 1 << 14 | Group2, 
    Group2Item3 = 1 << 15 | Group2, 

    Group3Item1 = 1 << 16 | Group3, 
    Group3Item2 = 1 << 17 | Group3, 
    Group3Item3 = 1 << 18 | Group3, 
} 

Затем вы можете использовать Enum.GetValues и HasFlag, чтобы получить значения для данных «группировок ":

var group1 = Enum.GetValues(typeof(MySuperEnumGroup)) 
       .Cast<MySuperEnumGroup>() 
       .Where(value => value.HasFlag(MySuperEnumGroup.Group1)) 
       .ToArray();