[英]Subscribing an Action to any event type via reflection
考慮:
someControl.Click += delegate { Foo(); };
事件的論點是無關緊要的,我不需要它們,我對它們不感興趣。 我只想讓Foo()被調用。 通過反射沒有明顯的方法來做同樣的事情。
我想將上述內容翻譯成類似的內容
void Foo() { /* launch missiles etc */ }
void Bar(object obj, EventInfo info)
{
Action callFoo = Foo;
info.AddEventHandler(obj, callFoo);
}
此外,我不想假設傳遞給Bar的對象類型嚴格遵守使用事件的EventHander(TArgs)簽名的指導原則。 簡而言之,我正在尋找一種方法來將Action訂閱到任何處理程序類型; 不那么簡單,一種將Action委托轉換為預期處理程序類型的委托的方法。
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);
}
這個怎么樣?
void Bar(object obj, EventInfo info)
{
var parameters = info.EventHandlerType.GetMethod("Invoke").GetParameters()
.Select(p => Expression.Parameter(p.ParameterType));
var handler = Expression.Lambda(
info.EventHandlerType,
Expression.Call(
Expression.Constant(obj), // obj is the instance on which Foo()
"Foo", // will be called
null
),
parameters
);
info.AddEventHandler(obj, handler.Compile());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.