Оператор переключения хорошо приблизительно для 30 условий?

Я нахожусь в заключительных этапах создания синтаксического анализатора тега MP4 в .NET. Для тех, у кого есть опыт с метками музыки, Вы знали бы, что существует в среднем приблизительно 30 тегов. Если проверил различные типы циклов, и кажется, что оператор переключения со значениями Константы, кажется, способ пойти относительно ловли тегов в двоичном файле.

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

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

Править: Каждый думает, что я должен добавить теперь, когда, где обсуждение этого состоит в том, что функция является рекурсивной, я должен вытащить это условное выражение и передать данные методу, который я могу уничтожить?

17
задан deanvmc 14 April 2010 в 20:22
поделиться

13 ответов

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

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

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

10
ответ дан 30 November 2019 в 10:49
поделиться

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

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

23
ответ дан 30 November 2019 в 10:49
поделиться

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

3
ответ дан 30 November 2019 в 10:49
поделиться

Я хотел добавить свой собственный ответ, чтобы оттолкнуть людей ...

  1. Создайте объект, содержащий «имя двоичного тега», «Данные», «Имя свойства».
  2. Создайте список из них, суммируя количество известных тегов, добавив имя тега и имя свойства.
  3. При синтаксическом анализе используйте linq, чтобы сопоставить найденное имя с object.binarytagname и добавить данные
  4. отразить в свойстве и добавить данные ...
0
ответ дан 30 November 2019 в 10:49
поделиться

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

1
ответ дан 30 November 2019 в 10:49
поделиться

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

5
ответ дан 30 November 2019 в 10:49
поделиться

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

2
ответ дан 30 November 2019 в 10:49
поделиться

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

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

1
ответ дан 30 November 2019 в 10:49
поделиться

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

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
ответ дан 30 November 2019 в 10:49
поделиться

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

2
ответ дан 30 November 2019 в 10:49
поделиться

Что о старый добрый цикл? Я думаю, вы можете так спроектировать. Разве switch-case в любом случае не преобразуется только в if-else? Я всегда стараюсь писать код с использованием цикла, если количество операторов case становится выше допустимого. А 30 случаев в свитче для меня слишком много.

0
ответ дан 30 November 2019 в 10:49
поделиться

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

public void SomeMethod(object obj)
{
  ITag it = obj as ITag;

  if(it != null)
  {
    it.SomeProperty = "SomeValue";
    it.DoSomthingWithTag();
  }
}
0
ответ дан 30 November 2019 в 10:49
поделиться

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

0
ответ дан 30 November 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: