c# - c#动态事件订阅和退订
问题描述
我希望能够让一个对象将其方法之一添加到EventHandler
传递给它的方法中,并赋予所述方法从EventHandler
.
public class EventRaiser {
public event EventHandler event1
public event EventHandler event2
public void fire() {
event1?.Invoke(this, null);
event2?.Invoke(this, null);
}
}
public class EventSubscriber {
EventHandler eh;
public EventSubscriber(EventHandler eh) {
this.eh = eh;
eh += receive;
}
public void receive(object obj, EventArgs data) {
// Do stuff.
if(condition) eh -= receive;
}
}
public class MainClass {
public void Main() {
EventRaiser er = new EventRaiser();
EventSubscriber es1 = new EventSubscriber(er.event1);
EventSubscriber es2 = new EventSubscriber(er.event2);
er.fire();
}
}
上面的代码无法编译,因为我什至无法传递er.event1
或er.event2
传递EventSubscriber
(“事件只能出现在 +=... 的左侧”)。从 s中删除event
关键字EventHandler
可解决此问题,但取消订阅无法正常工作。有没有办法使这项工作?也许使用指针?
解决方案
这里的问题来自你传递一个s ,而不是它本身包含 sEventHandler
的列表。delegate
基本上是处理程序的“方法指针列表”。
如您所见,在您的声明中event1
有关键字event
,当您将其传递到其他地方时,它会丢失。不幸的是,您无法轻松提取 a 的“delegate
持有人” event
。
+=
基本上,当您想将处理程序注册到某个事件时,您以某种方式需要对其进行编译时引用,以便能够对它进行引用-=
。
您可以执行以下操作:
public class EventRaiser
{
public delegate void Event1(string args);
public List<Event1> handlers = new List<Event1>();
public void register(Event1 handler)
{
handlers.Add(handler);
}
public void unregister(Event1 handler)
{
handlers.Remove(handler);
}
public void fire()
{
handlers.ForEach(handler => handler("myEventArgs"));
}
}
public class EventSubscriber
{
Action<Event1> registerAction;
Action<Event1> unregisterAction;
public EventSubscriber(Action<Event1> register, Action<Event1> unregister)
{
registerAction = register;
unregisterAction = unregister;
registerAction(receive);
}
public void receive(string args)
{
// Do stuff.
unregisterAction(receive);
}
}
public class MainClass
{
public void Main()
{
EventRaiser er = new EventRaiser();
EventSubscriber es1 = new EventSubscriber(er.register, er.unregister);
er.fire();
}
}
推荐阅读
- spring-boot - Ehcache Mbean 在 Hawtio GUI 中不可见
- java - 如何获取要插入到 Sqlite 的 imageView 值?
- c++ - 以最低延迟获得自午夜以来的纳秒
- javascript - 我如何传递匹配的 id?
- c# - 根据条件使用另一个列表中的值更新一个列表
- java - Java中的随机播放问题(复发?)
- python - 在 vscode 中丢失了 python 语法高亮
- amazon-web-services - 有没有办法使用 Node.js 确定 AWS DynamoDB 项目中的属性类型?
- algorithm - 从两个集合中返回第 j 个最小元素的算法
- sql - 是否可以在 Oracle SQL 中自动创建触发器?