Является ли оператор switch нормальным для 30 или около того условий? - PullRequest
17 голосов
/ 14 апреля 2010

Я нахожусь на завершающей стадии создания парсера тегов MP4 в .Net. Для тех, кто имеет опыт работы с тегами музыки, вы должны знать, что в среднем около 30 тегов. Если протестированы различные типы циклов и кажется, что оператор switch со значениями Const, кажется, является подходящим способом для отлова тегов в двоичном виде.

Переключатель позволяет мне выполнять поиск в двоичном файле без необходимости знать, в каком порядке хранятся теги, или если они присутствуют, но мне интересно, будет ли кто-то против использования оператора switch для стольких условных выражений.

Любое понимание очень ценится.

РЕДАКТИРОВАТЬ: Я думаю, что теперь я должен добавить, что при обсуждении этого является то, что функция является рекурсивной, я должен извлечь это условие и передать данные в метод, который я могу убить?

Ответы [ 13 ]

23 голосов
/ 14 апреля 2010

Возможно, с коммутатором он будет работать нормально, но я думаю, что ваша функция станет очень длинной.

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

10 голосов
/ 14 апреля 2010

Лично, если вам нужно, я бы пошел по этому пути. Оператор switch гораздо легче читать, чем оператор If / Else (и он будет оптимизирован для вас).

Вот связанный вопрос. Обратите внимание, что принятый ответ является неправильным.

Есть ли существенная разница между использованием if / else и switch-case в C #?

5 голосов
/ 14 апреля 2010

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

3 голосов
/ 14 апреля 2010

Для чего-то низкого уровня, подобного этому, я не вижу проблемы. Просто убедитесь, что вы помещаете каждый случай в отдельный метод. Вы будете благодарить себя позже.

2 голосов
/ 15 апреля 2010

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

2 голосов
/ 14 апреля 2010

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

1 голос
/ 15 апреля 2010

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

class DoStuff
{
   public void Do(type it, Context context )
   {
      switch(it)
      {
          case case1: doCase1(context) break;
          case case2: doCase2(context) break;
          //...
      }
   }
   protected abstract void doCase1(Context context);
   protected abstract void doCase2(Context context);
   //...
}

class DoRealStuff : DoStuff
{
   override void doCase1(Context context) { ... }
   override void doCase2(Context context) { ... }
   //...
}
1 голос
/ 15 апреля 2010

ID3Sharp на Sourceforge имеет http://sourceforge.net/projects/id3sharp/ использует более объектно-ориентированный подход с FrameRegistry, который раздает производные классы для каждого типа кадра.

Это быстро, хорошо работает и легко обслуживается. Затраты на создание небольшого объекта класса в C # незначительны по сравнению с открытием файла MP4 для чтения заголовка.

1 голос
/ 15 апреля 2010

Трудно сказать, не видя ваш код, но если вы просто пытаетесь поймать каждый тег, вы можете определить массив допустимых тегов, а затем просмотреть цикл, проверяя, есть ли каждый тег в массиве.

0 голосов
/ 15 апреля 2010

У вас почти наверняка есть цепочка ответственности в вашей проблеме. Рефакторинг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...