在通用逆变接口

时间:2018-05-09 14:31:47

标签: c# generics dynamic casting

我有这个界面:

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 { ... }

如何调用我的处理程序?

0 个答案:

没有答案