【发布时间】:2015-05-18 11:16:00
【问题描述】:
我正在尝试将委托附加到不同委托的调用列表。 通过这一点,我正在实现一种对现有事件的钩子。 我需要连接在每个被调用的事件之后运行的东西。
只要类型公开的委托和我传入的操作具有完全相同的签名,以下示例有效。 (On1 和 OnAll 事件均使用 Action 委托声明,因此可以正常工作)。
代码:我如何将 Action 与事件修饰符公开的现有委托挂钩。
public static class ReflectionExtensions
{
public static IEnumerable<EventInfo> GetEvents(this object obj)
{
var events = obj.GetType().GetEvents();
return events;
}
public static void AddHandler(this object obj, Action action)
{
var events = obj.GetEvents();
foreach (var @event in events)
{
@event.AddEventHandler(obj, action);
}
}
}
样本:
public class Tester
{
public event Action On1;
public event Action On2;
public void RaiseOn1()
{
On1();
}
public void RaiseOn2()
{
On2();
}
}
class Program
{
static void Main(string[] args)
{
var t = new Tester();
t.On1 += On1;
t.On2 += On2;
t.AddHandler(OnAll);
t.RaiseOn1();
t.RaiseOn2();
}
public void On1() { }
public void On2() { }
public void OnAll() { }
}
问题:当在 Tester 中使用事件修饰符暴露的委托没有相同的签名时,我会得到一个非常想要且明显的异常,它指出(用我的话)@987654323 @ 不能添加到 Action<int> 的调用列表中。说得通。
为了清楚起见,我正在描述以下内容:
public event Action<int> On1;
public void On1(int i){}
我正在寻找的是一种创建另一个与 EventHandlerType 相同类型的委托的方法。为此,我需要创建一个带有 EventHandlerType 签名 i 的方法,该方法将在内部调用操作。
类似:
public static void AddHandler(this object obj, Action action)
{
var events = obj.GetEvents();
foreach (var @event in events)
{
// method with the signeture of EventHandlerType which does action();
MethodInfo wrapperMethod = WrapAction(@event.EventHandlerType, action);
Delegate handler = Delegate.CreateDelegate(@event.EventHandlerType, action.Target, wrapperMethod);
@event.AddEventHandler(obj, handler);
}
}
【问题讨论】:
-
您想将
Action<int>作为Action传递并将它们添加到AddHandler中? -
每次调用任何@event 的底层委托时,我都想调用一个动作(是的,为了参数,Action 类型)。我已经描述了我的尝试,但任何解决方案都会受到欢迎。
标签: c# reflection delegates