У меня есть этот интерфейс:
interface IHandler
{
Type Type { get; } // returns typeof(T).
}
interface IHandler<in T> : IHandler
where T : IEvent
{
void Invoke(T ev);
}
Тогда у меня есть функция, которая должна вызывать все Handler<T>.Invoke(T)
, которые принимают ev.GetType()
(это то, что делает GetHandlersFor(Type)
). Однако я не могу понять, как вызвать метод Invoke
:
public void Invoke(IEvent ev)
{
ImmutableArray<IHandler> selected;
lock (_listeners)
{
selected = GetHandlersFor(ev.GetType()).ToImmutableArray();
}
// first attempt
foreach (var tl in selected)
{
Debug.Assert(tl.Type.IsInstanceOfType(ev)); // my data structure invariant
((IHandler<IEvent>) tl).Invoke(ev); // InvalidCastException
}
// second attempt
foreach (dynamic tl in selected)
{
tl.Invoke(ev); // RuntimeBinderException
}
}
В первой попытке я получаю System.InvalidCastException: 'Unable to cast object of type 'MyHandler`1[ChatEvent]' to type 'IHandler`1[IEvent]'.'
Во второй попытке я получаю Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' does not contain a definition for 'Invoke''.
.
Мой отладчик показывает, что тип tl
равен MyHandler<ChatEvent>
, а тип ev
равен ChatEvent
. Если вам интересно, MyHandler определяется как class MyHandler<T> : IHandler<T> where T : IEvent { ... }
.
Как мне вызвать мои обработчики?