通过反射将Action <T>传递给泛型方法?

vex*_*exe 2 c# reflection delegates action

我知道有类似的问题,但我仍然无法解决我的问题.

我有一个EventManager静态类,它只是一个包装器EventManagerInternal,如下所示:

public static class EventManager
{
    public static void Subscribe<T>(Action<T> handler) where T : GameEvent
    {
        EventManagerInternal<T>.Subscribe(handler);
    }
    public static void Unsubscribe<T>(Action<T> handler) where T : GameEvent
    {
        EventManagerInternal<T>.Unsubscribe(handler);
    }
    public static void Raise<T>(T e) where T : GameEvent
    {
        EventManagerInternal<T>.Raise(e);
    }

    private static class EventManagerInternal<T> where T : GameEvent
    {
        private static Dictionary<Type, Action<T>> dic = new Dictionary<Type, Action<T>>();
        public static void Subscribe(Action<T> handler)
        {
            // sub code...
        }
        public static void Unsubscribe(Action<T> handler)
        {
            // unsub code...
        }
        public static void Raise(T e)
        {
            // raise code...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

public class OnRename : GameEvent { }

public void OnRenameHandler(OnRename e) { }

EventManager.Subscribe<OnRename>(OnRenameHandler); // <-- the statement that I wanna generate via reflection
Run Code Online (Sandbox Code Playgroud)

我的问题是:我想通过反射生成相同的东西(相同的用法示例,如^),但我无法做到.怎么做?

我设法使订阅方法正确:

MethodInfo subscribe = typeof(EventManager).GetMethod("Subscribe").MakeGeneric(typeof(GameEvent)); // right?
Run Code Online (Sandbox Code Playgroud)

但那么如何调用它传入OnRenameHandler

知道我有一个MethodInfoOnRenameHandler

MethodInfo handler = typeof(SomeType).GetMethod("OnRenameHandler");

subscribe.Invoke(null, WHAT_TO_PASS_HERE?);
Run Code Online (Sandbox Code Playgroud)

我尝试Delegate.CreateDelegate但没有到达任何地方,我不确定这是解决方案.

我看过几个链接,尝试过几个东西,但都没有用.

谢谢你的帮助 :)

Mar*_*zek 7

使用Delegate.CreateDelegate静态方法创建具有运行时已知类型的委托.第一个参数设置委托类型.

// get subscribe method info
var subscribe = typeof(EventManager).GetMethod("Subscribe")
                                    .MakeGenericMethod(typeof(OnRename));

// prepare delegate instance
var delegateType = typeof(Action<>).MakeGenericType(typeof(OnRename));
var methodInfo = typeof(TypeWithOnRenameHandlerMethod).GetMethod("OnRenameHandler");
var del = Delegate.CreateDelegate(delegateType, this, methodInfo);

// invoke subscribe method
subscribe.Invoke(null, new [] { del });
Run Code Online (Sandbox Code Playgroud)

如果需要在当前实例上调用该方法,请替换this为第二个Delegate.CreateDelegate参数.

PS.我以为你真的需要打电话Subscribe<OnRename>,而不是Subscribe<GameEvent>.如果我错了,请随时改回来.