如何将对象转换为Action <T>

Ben*_*ter 3 c# generics

我创建了一个简单的消息总线,用于排队和发布/发布事件.

我正在使用StructureMap来定位Action<T>事件的已注册处理程序(),但我不确定如何将它从StructureMap返回的对象中转换为可调用的操作.

既然我不能Action<object>说我假设Action<T>不是协变的?这可以换一种方式吗?

public class Bus
{
    private ConcurrentQueue<object> events = new ConcurrentQueue<object>();
    public void Queue<TEvent>(TEvent e)
    {
        events.Enqueue(e);
    }

    public void Emit()
    {
        object e;
        while (events.TryDequeue(out e))
        {
            var handlerType = typeof(Action<>).MakeGenericType(e.GetType());
            foreach (var handler in ObjectFactory.GetAllInstances(handlerType))
            {
                // how to invoke action?
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

既然我不能转向Action我假设Action不是协变的?

Action<T>逆变 -这是有道理的,因为Action<object>可以作为被处理Action<string>(既可以接受string基准),但一个Action<string>不能作为被处理Action<object>(你会期望它做的,如果你提供一个它非字符串引用?).

调用它的最简单方法可能只是用Delegate.DynamicInvoke来说实话 - 另一种方法是编写泛型方法并使用反射或使用调用它dynamic.