С точки зрения того, чтобы сделать его родовым ... ну, это возможно. У меня есть библиотека с именем Unconstrained Melody , которая использует перезапись IL для обобщений с ограничениями делегатов - и вы можете использовать тот же перезаписывающий IL в своем коде. Это довольно уродливо, хотя. По сути, IL поддерживает ограничение, которое вы хотите, а C # - нет. Обратите внимание, что нет никаких возможных ограничений для «это должен быть тип, производный от MulticastDelegate
, но не включающий MulticastDelegate
сам» ... так что кто-то может создать StringToMethodMapper<MulticastDelegate>
, но это довольно непривычно.
Если вы счастливы придерживаться одного вида подписи делегата (например, «всегда три параметра и возврат по пустоте»), тогда вы можете использовать подход из ответа Джорджа. Если это должно быть для любого типа делегата, то вы застряли с подходом переписывания IL или отказались от ограничения.
(Отредактировано на основе комментариев.)
С точки зрения остальной части кода, это очень медленное использование словаря. В настоящее время у вас есть O (n) поиск. Просто используйте обычный Dictionary
доступ через TryGetValue
, но передайте StringComparer.OrdinalIgnoreCase
(или что-то подобное) в конструктор, чтобы получить регистронезависимое совпадение. По общему признанию, это не приведет к совпадению «начинается с», но ваш текущий подход не является детерминированным, так как в итоге вы можете использовать «foo» и «fo» в качестве ключей в словаре, оба из которых будут совпадать - так что вы полагаетесь на порядок, в котором итератор возвращает ключи. Не очень хорошая идея.
Если вам действительно нужно поведение StartsWith
, возможно, вы захотите исследовать реализацию trie - или, если вы довольны O (N) поиском, я бы оставил List<KeyValuePair<string, TDelegate>>
, чтобы сделать ясно, что вы не используете его в качестве словаря.