Является ли инструкция switch ok на 30 или около того условий?
Я нахожусь на заключительной стадии создания парсера тегов MP4 в .NET. Для тех, у кого есть опыт работы с тегами музыки, вы будете знать, что в среднем около 30 или около того тегов. Если тестируются различные типы циклов, и кажется, что оператор switch с значениями Const, похоже, подходит для улавливания тегов в двоичном формате.
Этот переключатель позволяет мне искать двоичный файл без необходимости знать, какой заказ хранятся в тегах или есть некоторые, но мне интересно, не будет ли кто-либо против использования оператора switch для стольких условностей.
Любое понимание очень ценится.
EDIT: Думаю, теперь я должен добавить, что там, где обсуждается это, функция рекурсивна, следует ли вытащить это условное выражение и передать данные методу, который я могу убить?
Ответы
Ответ 1
Лично, если нужно, я бы пошел так. Оператор switch гораздо проще читать, чем инструкции If/Else (и ваш размер будет оптимизирован для вас).
Вот связанный вопрос. Обратите внимание, что принятый ответ неверен.
Есть ли существенная разница между использованием if/else и switch-case в С#?
Ответ 2
Скорее всего, он будет работать с коммутатором, но я думаю, что ваша функция станет очень длинной.
Один из способов решения этой проблемы - создать класс обработчика для каждого типа тега, а затем зарегистрировать каждый обработчик соответствующим тегом в словаре. Когда вам нужно проанализировать тег, вы можете искать в словаре, который должен использоваться обработчик.
Ответ 3
Другая опция (Python inspired) - это словарь, который сопоставляет тег с лямбда-функцией или событием или что-то в этом роде. Это потребует некоторой реструктуризации.
Ответ 4
Для чего-то низкого уровня, подобного этому, я не вижу проблемы. Просто убедитесь, что вы помещаете каждый случай в отдельный метод. Вы поблагодарите себя позже.
Ответ 5
Мне, имея столько условий в инструкции switch, дает мне разум для размышлений. Возможно, было бы лучше реорганизовать код и полагаться на виртуальные методы, ассоциацию между тегами и методами или любой другой механизм, чтобы избежать кода спагетти.
Ответ 6
Если у вас есть только одно место, которое имеет определенную структуру операторов switch
и case
, то это вопрос стиля. Если у вас более одного места с одинаковой структурой, вам может потребоваться переосмыслить, как вы это делаете, чтобы минимизировать головные боли обслуживания.
Ответ 7
Трудно сказать, не видя ваш код, но если вы просто пытаетесь поймать каждый тег, вы можете определить массив допустимых тегов, а затем прокрутите файл, проверяя, есть ли каждый тег в массиве.
Ответ 8
ID3Sharp на Sourceforge имеет http://sourceforge.net/projects/id3sharp/ использует более объектно-ориентированный подход с FrameRegistry, который передает производные классы для каждого типа фрейма.
Это быстро, он работает хорошо, и его легко поддерживать. "Накладные расходы" на создание объекта небольшого класса в С# незначительны по сравнению с открытием файла MP4 для чтения заголовка.
Ответ 9
Один проект, который может быть полезен в некоторых случаях (но из того, что я видел, было бы убито здесь):
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) { ... }
//...
}
Ответ 10
Я не знаком с технологией MP4, но я бы рассмотрел возможность использования некоторых интерфейсов здесь. Передайте объект, попробуйте применить его к интерфейсу.
public void SomeMethod(object obj)
{
ITag it = obj as ITag;
if(it != null)
{
it.SomeProperty = "SomeValue";
it.DoSomthingWithTag();
}
}
Ответ 11
Я хотел добавить свой собственный ответ, чтобы отбросить людей...
- Создайте объект, который содержит "имя двоичного тега", "Данные", "Имя свойства".
- Создайте список из них, в котором будет указано количество известных тегов, добавив имя тега и имя свойства.
- При анализе используйте linq для соответствия найденному имени с object.binarytagname и добавьте данные
- отразить в свойстве и добавить данные...
Ответ 12
Как насчет хорошего старого цикла? Я думаю, вы можете спроектировать его таким образом. Разве это не коммутационный регистр, преобразованный if-else? Я всегда стараюсь писать код, используя цикл, если количество аргументов case становится выше допустимого. И 30 случаев в переключателе слишком высоки для меня.
Ответ 13
У вас почти наверняка есть цепочка ответственности в вашей проблеме. Рефакторинг.