c#静态事件处理程序与非静态事件处理程序
本文关键字:程序 事件处理 静态 | 更新日期: 2023-09-27 18:13:39
大家好!我想了解以下问题:
假设我们有一个简单的EventSubscriber类
public class EventSubscriber
{
public static Delegate AddEventHandler(object target, string eventName, Action<object, EventArgs> action)
{
EventInfo eventInfo = target.GetType().GetEvent(eventName);
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, action.Method);
eventInfo.AddEventHandler(target, handler);
return handler;
}
public static void RemoveEventHandler(object target, string eventName, Delegate handler)
{
var eventInfo = target.GetType().GetEvent(eventName);
eventInfo.RemoveEventHandler(target, handler);
}
}
假设我们有一个计时器我们想订阅流逝事件
class Program
{
static System.Timers.Timer timer;
public static void InitTimer(int interval)
{
timer = new System.Timers.Timer(interval);
timer.Start();
}
static void Main(string[] args)
{
int interval = 1000;
InitTimer(interval);
var handler = EventSubscriber.AddEventHandler(timer, "Elapsed", Handler);
Thread.Sleep(Convert.ToInt16(interval * 5));
EventSubscriber.RemoveEventHandler(timer, "Elapsed", handler);
Thread.Sleep(Convert.ToInt16(interval * 5));
}
public static void Handler(object sender, EventArgs args)
{
Console.WriteLine("BOOO");
}
}
现在,如果你编译这个应用程序,一切都会正常工作,你会看到应用程序的预期行为。让我们在类中包装定时器:
public class TimerWrapper
{
public System.Timers.Timer Timer { get; set; }
public int Interval { get; set; }
public TimerWrapper(int interval)
{
Interval = interval;
Timer = new System.Timers.Timer(Interval);
Timer.Start();
}
public static void Handler(object sender, EventArgs args)
{
Console.WriteLine("BOOO");
}
}
现在让我们检查一下:
class Program
{
static void Main(string[] args)
{
int interval = 1000;
TimerWrapper timerWrapper = new TimerWrapper(interval);
var handler = EventSubscriber.AddEventHandler(timerWrapper.Timer, "Elapsed", TimerWrapper.Handler);
Thread.Sleep(Convert.ToInt16(interval * 5));
EventSubscriber.RemoveEventHandler(timerWrapper.Timer, "Elapsed", handler);
Thread.Sleep(Convert.ToInt16(interval * 5));
}
}
一切正常。但是,如果我们将我们的处理程序在TimerWrapper非静态和运行应用程序呢?我们将收到系统。无法绑定到目标方法,因为其签名或安全透明度与委托类型的签名或安全透明度不兼容。
我有一些猜想,但我想确切地知道为什么会这样。
我希望得到全面的答案,提前感谢,感谢您的时间!
问题是,你调用Delegate.CreateDelegate
与一个过载,预计工作的静态方法(或例如方法,有一个额外的委托参数,这是方法调用的目标)。
要让它工作,你所需要做的就是在创建新委托时传递现有委托的目标:
Delegate handler = Delegate.CreateDelegate(
eventInfo.EventHandlerType,
action.Target,
action.Method);
如果原始委托(action
)使用静态方法,action.Target
将已经是null
,所以这是好的