使用反射指定委托的类型(附加到事件)
本文关键字:事件 类型 反射 | 更新日期: 2023-09-27 17:58:19
我实际上想做的是这样的事情(我意识到这不是有效的代码):
// Attach the event.
try
{
EventInfo e = mappings[name];
(e.EventHandlerType) handler = (sender, raw) =>
{
AutoWrapEventArgs args = raw as AutoWrapEventArgs;
func.Call(this, args.GetParameters());
};
e.AddEventHandler(this, handler);
}
...
现在我知道e.EventHandlerType将始终从EventHandler<AutoWrapEventArgs>。然而,我不能只做:
EventHandler<AutoWrapEventArgs> handler = (sender, raw) =>
{
AutoWrapEventArgs args = raw as AutoWrapEventArgs;
func.Call(this, args.GetParameters());
};
e.AddEventHandler(this, handler);
作为。NET抱怨没有适用于EventHandler的转换<AutoWrapEventArgs>到EventHandler<DataEventArgs>当调用AddEventHandler时。这就是确切的信息:
Object of type 'System.EventHandler`1[IronJS.AutoWrapObject+AutoWrapEventArgs]'
cannot be converted to type
'System.EventHandler`1[Node.net.Modules.Streams.NodeStream+DataEventArgs]'.
我还尝试过使用Invoke来动态使用e.EventHandlerType的构造函数,但无法将委托定义传递给Invoke()的参数列表(因为没有从委托到对象的转换)。
有没有一种方法可以让我利用反思来解决这个问题?
宾果!诀窍是获得对委托类型的构造函数的引用,然后使用以下参数调用它:
- 委托的目标对象(backend.target)
- 委托的指针(backend.Method.MethodHandle.GetFunctionPointer())
执行此操作的实际代码看起来像(本例中的t是在继承过程中提供给EventHandler<>的通用参数):
Type t = e.EventHandler.GetGenericArguments()[0];
Delegate handler = (Delegate)
typeof(EventHandler<>)
.MakeGenericType(t)
.GetConstructors()[0]
.Invoke(new object[]
{
backend.Target,
backend.Method.MethodHandle.GetFunctionPointer()
});
然后,您可以使用委托来添加事件,如下所示:
e.AddEventHandler(this, handler);
您可以使用Delegate.CreateDelegate
来实现这样的目标:
public void RegisterHandler(string name)
{
EventInfo e = mappings[name];
EventHandler<AutoWrapEventArgs> handler = (s, raw) =>
{
func.Call(this, raw.GetParameters());
};
e.AddEventHandler(this, Delegate.CreateDelegate(e.EventHandlerType, null, handler.Method));
}