Вы бы использовали регионы в длинных объявлениях switch/enum?

Недавно я обнаружил, что мне нужно (да, нужно) определить абсурдно длинные операторы switch и объявления enum в коде C#, но мне интересно, как люди считают, что это лучший способ разделить их на логические подразделы. В моей ситуации как значения перечисления, так и случаи (которые основаны на значениях перечисления) имеют довольно четкие группы, но я немного не уверен, как отразить это в коде.

Обратите внимание, что в моем коде у меня есть примерно 5 групп от 10 до 30 значений/случаев перечисления в каждой.

Я могу представить себе три смутно разумных варианта:

  1. Определите блоки #region вокруг всех логических групп значений case/enum в объявлении (необязательно разделенных пустыми строками).
  2. Прокомментируйте каждую группу ее именем, поставив пустую строку перед каждым комментарием имени группы.
  3. Ничего не делайте - просто оставьте переключатель/перечисление в виде огромного списка случаев/значений.

Что вы предпочитаете? Не могли бы вы рассматривать перечисления и переключатели отдельно? (Мне это показалось бы немного странным.) Теперь я бы не сказал, что на этот вопрос есть какой-то правильный/неправильный ответ, хотя мне, тем не менее, было бы очень интересно услышать каков общий консенсус мнений.

Примечание 1. Эта ситуация, когда у меня потенциально может быть очень длинное объявление enum из 50/100+ значений, к сожалению, неизбежна (и аналогично с переключателем), поскольку я пытаюсь написать лексер (токенизатор) , и, таким образом, это представляется наиболее разумным подходом по нескольким причинам.

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


person Community    schedule 26.06.2009    source источник
comment
только что отредактировал мой ответ. Надеюсь, поможет :)   -  person Samuel Carrijo    schedule 26.06.2009


Ответы (6)


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

Они существуют не просто так, используйте их в своих интересах.

person Community    schedule 26.06.2009
comment
Это было в значительной степени моим размышлением, прежде чем я задал этот вопрос. Я склонен считать чрезмерное использование регионов чем-то злым, но это, похоже, исключение. - person Noldorin; 26.06.2009

У вас также может быть Dictionary‹[your_enum_type], Action> (или Func вместо Action) или что-то в этом роде (учитывая, что ваши функции имеют аналогичную сигнатуру). Тогда вы могли бы вместо использования переключателя вместо:

        switch (item)
        {
            case Enum1: func1(par1, par2)
                break;
            case Enum2: func2(par1, par2)
                break;
        }

у вас может быть что-то вроде:

public class MyClass
{
    Dictionary<int, Action<int, int>> myDictionary;
    //These could have only static methods also
    Group1Object myObject1;
    Group2Object myObject2;

    public MyClass()
    {
        //Again, you wouldn't have to initialize if the functions in them were static
        myObject1 = new Group1Object();
        myObject2 = new Group2Object();
        BuildMyDictionary();
    }

    private Dictionary<int, Action<int, int>> BuildMyDictionary()
    {
        InsertGroup1Functions();
        InsertGroup2Functions();
        //...
    }

    private void InsertGroup2Functions()
    {
        myDictionary.Add(1, group2.AnAction2);
        myDictionary.Add(2, group2.AnotherAction2);
    }

    private void InsertGroup1Functions()
    {
        myDictionary.Add(3, group1.AnAction1);
        myDictionary.Add(4, group1.AnotherAction1);
    }


    public void DoStuff()
    {
        int t = 3; //Get it from wherever
        //instead of switch
        myDictionary[t](arg1, arg2);
    }
}
person Community    schedule 26.06.2009
comment
Этот метод, безусловно, имеет свои преимущества во многих случаях (особенно при использовании длинных гильз). Однако для меня это на самом деле только перенос случаев оператора switch на метод, добавляющий элементы в словарь, и на самом деле не помогает с группировкой. - person Noldorin; 26.06.2009
comment
ИМХО, это не совсем то же самое - это хороший способ разделить эти строки добавления словаря на несколько методов. Это также дает вам дополнительный уровень абстракции с помощью делегатов — вы можете добавить любого делегата в список из любого места вашего кода. - person Groo; 27.06.2009
comment
@samuel: Спасибо за добавление примера кода. Действительно, то, как вы можете разделить инициализацию словаря на методы, весьма выгодно. Теперь мне начинает нравиться это решение. :) - person Noldorin; 27.06.2009

Я бы оставил это как огромный список случаев/значений.

person Community    schedule 26.06.2009
comment
Причина в том, что вы не любите регионы вообще, я так понимаю? (Возможно, это справедливое замечание.) - person Noldorin; 26.06.2009
comment
Я не люблю регионы вообще или в данном конкретном случае :). Мне нравится использовать ctrl + m + o, чтобы свернуть файлы классов. Регионы нарушают мое намерение, потому что вместо кода я вижу регион. - person David Silva Smith; 29.06.2009

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

person Community    schedule 26.06.2009
comment
Интересное предложение. Я не совсем знаком с шаблоном стратегии. Действительно ли это уместно здесь, в случае, если мое перечисление представляет собой набор видов токенов (и я пишу это для компилятора)? - person Noldorin; 26.06.2009
comment
Я не вижу большой проблемы в использовании Стратегии. По сути, вы создаете классы, отвечающие за выполнение логики внутри каждого блока case. Именно тот, кто создает экземпляр большего класса (тот, у кого есть блок-переключатель), определяет, какой логический класс он будет использовать. - person mkato; 26.06.2009

Избавьтесь от перечислений и превратите их в объекты. Затем вы можете вызывать методы для своих объектов и сохранять код разделенным, удобным для сопровождения, а не кошмаром.

Существует очень мало случаев, когда вам действительно нужно использовать перечисление вместо объекта, и никто не любит длинные операторы переключения.

person Community    schedule 26.06.2009
comment
Смотрите мою первую заметку. Это лексер (как часть компилятора) я пишу. Единственный подход, который я видел в существующем коде, — это использование перечисления, хотя в этих примерах он обычно определялся только для очень простой грамматики, поэтому группировка не требовалась. - person Noldorin; 26.06.2009
comment
Я не думаю, что это меняет мой ответ. Не видя источника, я должен верить, что их можно разбить на ценностные объекты. - person Bryan Rowe; 26.06.2009
comment
К сожалению, мне действительно нужно указать значения с какой-то одной структурой данных. Я должен был указать, что перечисление представляет тип токена в лексере и должно храниться в структуре Token. - person Noldorin; 26.06.2009
comment
Хорошо. Так почему бы не создать класс токенов с кучей статических конструкторов для каждого возможного вида токенов? Таким образом, у вас может быть что-то вроде: public static Token OneTypeOfToken(){ return new Token() } Вы можете передать в Token ctor делегат или важные функции, которые вы сейчас включаете. Тогда у вас будет просто коллекция токенов и сказать Token.DoSomething(); - person Bryan Rowe; 26.06.2009
comment
@Bryan: На самом деле это очень похоже на то, как я настроил его на данный момент. Однако это не устраняет необходимость в любом из случаев, если только я не понял неправильно. - person Noldorin; 27.06.2009

Вот хороший ярлык для людей, которые используют регионы.

Я переключался между Eclipse и Visual Studio, когда пытался перейти в полноэкранный режим в VS, нажав

Ctrl-M-M

и о чудо, регион закрылся и расширился!

person Community    schedule 26.06.2009
comment
Да, есть несколько удобных сокращений, которые, я думаю, делают регионы менее неприятными, чем они могли бы быть. :) - person Noldorin; 27.06.2009