Подмножество Enum или подгруппа в С#
У меня есть существующее перечисление с многочисленными элементами в нем.
У меня также есть существующий код, который делает определенные вещи с этим перечислением.
Теперь мне хотелось бы просмотреть только элементы перечисления подмножества. То, что я ищу, - это способ разделить мой enum на группы. Мне нужно сохранить значение (int) каждого члена, и мне нужно сохранить возможность просмотра всех членов перечисления, если это необходимо.
Единственное, что я могу придумать, это просто создать новое перечисление для каждого подменю, которое содержит только те элементы, которые я хочу использовать с тем же именем и значением.
Это работает, но нарушает весь принцип повторения.
Я не ожидаю, что у кого-то будет лучшая альтернатива, но я подумал, что попрошу на всякий случай, если у кого-то будет фантастический трюк, чтобы показать мне.
Спасибо, как всегда.
Ответы
Ответ 1
В конце концов, мне пришлось переписать большую часть кода, но был получен следующий "трюк":
Я разбил С# перечисления и использовал статические члены в обычном классе. Этот класс был сделан в одноэлементный режим и включен в начало приложения.
Конструкторам статических членов разрешено ссылаться на другой статический член как "родительский".
Затем мой метод init использует рефлексию для прохождения каждого статического члена и индексирует их на основе нескольких свойств. Эти индексы хранятся в хэш-таблицах, которые также являются членами singleton.
Я получаю:
одноэлементный объект, который:
- имеет статические элементы, к которым можно легко получить доступ во время разработки.
- может использоваться во время выполнения для поиска определенных статических членов (на основе "группы" и других свойств).
Мой метод init делает справедливую проверку. Если создаются недействительные (например, повторяющиеся) статические члены, вы получаете ошибку во время запуска приложения.
Очевидно, довольно большой взлом, но я вполне доволен им.
Ответ 2
Вы можете определить значения, используя перечисление, но затем ссылаться на них через константы в статических классах, чтобы ваши разработчики не переутомили большой перечислитель. Вы могли бы:
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.
Ответ 3
Я бы пошел с этим (что работает в 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, когда вам нужно.
Ответ 4
Это может помочь: Fake Enums в С#
Ответ 5
Если перечисления не имеют явных значений, дайте им один и используйте флаги для определения "группировок":
[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();