Subscribing an Action to any event type via reflection(通过反射将 Action 订阅到任何事件类型)
问题描述
考虑:
someControl.Click += delegate { Foo(); };
事件的参数无关紧要,我不需要它们,我对它们不感兴趣.我只是想让 Foo() 被调用.没有明显的方法可以通过反射来做同样的事情.
The arguments of the event are irrelevant, I don't need them and I'm not interested in them. I just want Foo() to get called. There's no obvious way to do the same via reflection.
我想将以上内容翻译成类似
I'd like to translate the above into something along the lines of
void Foo() { /* launch missiles etc */ }
void Bar(object obj, EventInfo info)
{
Action callFoo = Foo;
info.AddEventHandler(obj, callFoo);
}
另外,我不想假设传递给 Bar 的对象类型严格遵守对事件使用 EventHander(TArgs) 签名的准则.简而言之,我正在寻找一种将 Action 订阅到任何处理程序类型的方法;不太简单,一种将 Action 委托转换为预期处理程序类型的委托的方法.
Also, I don't want to make the assumption that the type of object passed to Bar strictly adheres to the guidelines of using the EventHander(TArgs) signature for events. To put it simply, I'm looking for a way to subscribe an Action to any handler type; less simply, a way to convert the Action delegate into a delegate of the expected handler type.
推荐答案
static void AddEventHandler(EventInfo eventInfo, object item, Action action)
{
var parameters = eventInfo.EventHandlerType
.GetMethod("Invoke")
.GetParameters()
.Select(parameter => Expression.Parameter(parameter.ParameterType))
.ToArray();
var handler = Expression.Lambda(
eventInfo.EventHandlerType,
Expression.Call(Expression.Constant(action), "Invoke", Type.EmptyTypes),
parameters
)
.Compile();
eventInfo.AddEventHandler(item, handler);
}
static void AddEventHandler(EventInfo eventInfo, object item, Action<object, EventArgs> action)
{
var parameters = eventInfo.EventHandlerType
.GetMethod("Invoke")
.GetParameters()
.Select(parameter => Expression.Parameter(parameter.ParameterType))
.ToArray();
var invoke = action.GetType().GetMethod("Invoke");
var handler = Expression.Lambda(
eventInfo.EventHandlerType,
Expression.Call(Expression.Constant(action), invoke, parameters[0], parameters[1]),
parameters
)
.Compile();
eventInfo.AddEventHandler(item, handler);
}
用法:
Action action = () => BM_21_Grad.LaunchMissle();
foreach (var eventInfo in form.GetType().GetEvents())
{
AddEventHandler(eventInfo, form, action);
}
这篇关于通过反射将 Action 订阅到任何事件类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:通过反射将 Action 订阅到任何事件类型
基础教程推荐
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- c# Math.Sqrt 实现 2022-01-01