Есть много дорог, которые ведут в Рим, и есть немало способов, которыми вы можете решить свою проблему. Один простой подход заключается в использовании общего абстрактного базового класса для ваших конкретных типов обработчиков событий, который может обеспечить метод Handle(TEvent evt)
.
public abstract class HandlerBase<T> where T : TEvent, new()
{
public abstract void Handle(T evt);
public void Handle(TEvent evt)
{
if (!(evt is T))
{
throw new ArgumentException("This handler does not support the event type " + evt.GetType().FullName);
}
Handle((T) evt);
}
}
Ваши конкретные обработчики событий будут производными от этого абстрактного базового класса, аналогично следующему примеру кода:
public class SpecificEventHandler: HandlerBase<SpecificEvent>
{
public override void Handle(SpecificEvent evnt)
{
....
}
}
Код из вашего вопроса может быть упрощен как:
foreach (var evt in eventItems)
{
...
dynamic eventHandler = ResolveEventHandler(evt.GetType().Name);
eventHandler.Handle(evt);
}
Кроме того, чтобы запретить указывать обработчик событий с самим TEvent
в качестве параметра универсального типа, объявите TEvent как абстрактный класс или превратите его в интерфейс (обратите внимание на ограничение new()
, которое я использовал для HandlerBase выше, что позволяет использовать только конкретные, инстанцируемые типы в качестве параметра универсального типа). Использование самого TEvent
в качестве параметра общего типа для класса HandlerBase, показанного выше, приведет к двум методам Handle с одинаковой сигнатурой, что приведет к ошибке компиляции.