我想动态调用lambda表达式,但我得到的只是methodInfo。
类似的东西:
Magic.RegisterStaticPacketHandler<TestPacket>((a, b) => { /* Do Stuff */ });
Magic class:
public void RegisterStaticPacketHandler<T>(PacketReceivedHandler<T> handler) where T : Packet
{
//Remember the handler with: handler.GetMethodInfo()
}
后来我想调用这个方法。因为PacketReceivedHandler是一个委托,所以我可以从中获取“MethodInfo”。如果我只用:
调用这个MethodInfomethodInfo.Invoke(obj, new object[] { packet, this });
我的ofc收到一个异常,即给定的对象(obj)不适合。 设置像“NonPublic | Instance | Static”这样的BindingFlags也没有帮助。
更新
PacketReceivedHandler看起来如下:
public delegate void PacketReceivedHandler<T>(T packet, Connection connection) where T : Packet;
我把它保存在我的Magic课程中:
private Dictionary<int, Tuple<MethodInfo, object>> id_methodInfo_object = new Dictionary<int, Tuple<MethodInfo, object>>();
答案 0 :(得分:3)
除了方法之外,您还必须保存委托的Target
。最简单的方法是直接存储整个代理本身而不是MethodInfo
。像这样:
// Store any lambda or action or anything in their baseclass "Delegate":
Delegate act = new Action<int, int>((a, b) => Console.WriteLine(a + b));
// Dynamically invoke like this:
act.Method.Invoke(act.Target, new object[] {4, 9});
完整示例:
class Program
{
private static List<Delegate> handlers = new List<Delegate>();
public static void RegisterHandler<T>(Action<T> del)
{
handlers.Add(del);
}
public static void InvokeHandlers(params object[] args)
{
foreach (var h in handlers)
{
h.Method.Invoke(h.Target, args);
}
}
static void Main(string[] args)
{
RegisterHandler((object a) => Console.WriteLine("#1:" + a));
RegisterHandler((object a) => Console.WriteLine("#2:" + a));
InvokeHandlers("foo");
InvokeHandlers(1234);
}
}
答案 1 :(得分:0)
public void RegisterStaticPacketHandler<T>(PacketReceivedHandler<T> handler) where T : Packet
{
_methodInfo = handler.Method;
}
请参阅MSDN
中的详细信息