Словарь с делегатом или переключателем?
Я пишу парсер, который вызывает некоторые функции, зависящие от некоторого значения.
Я могу реализовать эту логику с помощью простого переключателя следующим образом:
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();
Являются ли эти два метода эквивалентными и какой является предпочтительным?
6 ответов
С точки зрения доступа они идентичны: оба просто проверяют, имеет ли это конкретное значение соответствующий результат. Тем не менее, Словарь выдаст исключение вне пределов, если вы попытаетесь получить доступ к несуществующему ключу.
Выбор должен быть в первую очередь на повторное использование. Если вам нужно сделать эту логику ветвления только в одной точке, то использование регистра-переключателя, вероятно, имеет больше смысла, чем сохранение переменной. Если вам нужно обращаться к нему несколько раз в отдельных точках, используйте словарь, чтобы уберечь себя от повторного вставления оператора switch.
Я настоятельно предпочитаю выбор словаря, потому что с инициализатором он может быть намного более компактным и читаемым:
var actions = new Dictionary<int, Action>
{
{1, () => Console.WriteLine("One!")},
{2, () => Console.WriteLine("Two!")}
}
Кроме того, у вас есть больше гибкости; Вы можете добавлять условия и действия программно, что часто удобно, в зависимости от того, что вы делаете.
Если типичный программист в вашей команде похож на тех, с которыми я часто сталкиваюсь, вам следует выбрать самый простой вариант - переключение. Делегаты кажутся мне "умным" решением, которое не нужно.
Мне нравится словарный подход, потому что он дает вам возможность поменять лямбда-выражения по мере необходимости. Это отличный трюк для программиста, чтобы держать его в сумке с инструментами для случаев, связанных с программами, использующими сложные деревья решений. Было бы очень неудобно модифицировать ваши блоки переключателей во время выполнения, и лучший ответ в любом случае был бы связан с лямбдами.
Однажды у меня была ситуация, когда мне нужно было динамически создать оператор switch. Этот метод предоставил намного более удобочитаемое решение.
Оба делают то же самое (хорошо, вы должны проверить, появляется ли ключ в диктонаре).
Это просто вопрос читабельности. Что выглядит лучше для вас и, что более важно, что предпочитают люди, читающие ваш код.
(Думаю, словарь)
Если вам нужно включить строки в файле ресурсов, скажем, в целях глобализации, то вам нужно будет использовать подход словарь / делегат.