Reputation: 5615
I know there's similar questions to this but I still wasn't able to resolve my issue.
I have a EventManager
static class, which is just a wrapper for EventManagerInternal
, like so:
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...
}
}
}
Example usage:
public class OnRename : GameEvent { }
public void OnRenameHandler(OnRename e) { }
EventManager.Subscribe<OnRename>(OnRenameHandler); // <-- the statement that I wanna generate via reflection
My question is: I want to generate the same thing (same usage example like ^) via reflection but I'm unable to. How to do it?
I managed to get the subscribe method right:
MethodInfo subscribe = typeof(EventManager).GetMethod("Subscribe").MakeGeneric(typeof(GameEvent)); // right?
But then how to invoke it passing in OnRenameHandler
?
Knowing that I have a MethodInfo
to OnRenameHandler
MethodInfo handler = typeof(SomeType).GetMethod("OnRenameHandler");
subscribe.Invoke(null, WHAT_TO_PASS_HERE?);
I tried Delegate.CreateDelegate
but didn't get anywhere, I'm not sure it's the solution.
I've looked at several links, tried several things, but none worked.
Thanks for any help :)
Upvotes: 2
Views: 3920
Reputation: 125610
Use Delegate.CreateDelegate
static method to create delegate with a type known at runtime. First parameter sets the delegate type.
// 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 });
Replace this
as second Delegate.CreateDelegate
parameter if you need to call the method on other then current instance.
PS. I assumed that you really need to call Subscribe<OnRename>
, not Subscribe<GameEvent>
. Feel free to change it back if I'm wrong.
Upvotes: 9