Я пишу синтаксический анализатор, который вызывает некоторые функции, зависящие от некоторого значения.
Я могу реализовать эту логику с простым переключателем как это:
switch(some_val)
{
case 0:
func0();
break;
case 1:
func1();
break;
}
или с делегатами и словарем как это:
delegate void some_delegate();
Dictionary<int, some_delegate> some_dictionary = new Dictionary<int, some_delegate>();
some_dictionary[0] = func0;
some_dictionary[1] = func1;
some_dictionary[some_value].Invoke();
Действительно ли эти два метода эквивалентны и который предпочтен?
С точки зрения доступа они идентичны: оба просто проверяют, имеет ли это конкретное значение соответствующий результат. Однако словарь вызовет исключение за пределами допустимого диапазона, если вы попытаетесь получить доступ к несуществующему ключу.
В первую очередь следует выбирать возможность повторного использования. Если вам нужно сделать эту логику ветвления только в одной точке, тогда использование switch-case, вероятно, имеет больше смысла, чем сохранение переменной. Если вам нужно многократно обращаться к нему в отдельных точках, используйте Словарь, чтобы избавиться от простой повторной вставки оператора switch.
Я очень предпочитаю выбор словаря, потому что с инициализатором он может быть намного более компактным и читаемым:
var actions = new Dictionary<int, Action>
{
{1, () => Console.WriteLine("One!")},
{2, () => Console.WriteLine("Two!")}
}
Кроме того, у вас есть некоторая гибкость; вы можете добавлять условия и действия программно, что часто бывает удобно, в зависимости от того, что вы делаете.
Если типичный программист в вашей команде похож на тех, с которыми я часто имею дело, вам следует выбрать самый простой вариант, то есть переключение. Делегаты мне кажутся «умным» решением, в котором нет необходимости.
Оба делают то же самое (хорошо, вы должны проверить, появляется ли ключ в словаре).
Это просто вопрос удобочитаемости. Что лучше всего подходит для вас и что более важно, что предпочтут люди, читающие ваш код.
(думаю, словарь)