能否按EventClass的ExecuteOrder对EventHandler列表排序并按序调用?
问题:按EventClass实例的ExecuteOrder排序EventHandler列表并执行
定义的EventClass类
public class EventClass { public int ExecuteOrder {get; set;} public List<EventHandler> Children {get; set;} public EventClass(int order) { ExecuteOrder = order; Children = new List<EventHandler>(); } public void OnExecuteA(object sender, EventArgs e) { //Do something... } public void OnExecuteB(object sender, EventArgs e) { //Do something... } }
Main方法中的场景
public static void Main() { EventClass parent = new EventClass(0); EventClass child1 = new EventClass(1); EventClass child2 = new EventClass(2); EventClass child3 = new EventClass(3); EventClass child4 = new EventClass(4); EventClass child5 = new EventClass(5); parent.Children.Add(new EventHandler(child3.OnExecuteA)); parent.Children.Add(new EventHandler(child1.OnExecuteA)); parent.Children.Add(new EventHandler(child4.OnExecuteB)); parent.Children.Add(new EventHandler(child5.OnExecuteA)); parent.Children.Add(new EventHandler(child2.OnExecuteB)); //实际项目中是在不同模块添加,无法预知顺序,此处模拟无序添加 }
问题描述
能否将parent.Children列表排序为{child1,child2,child3,child4,child5}的顺序,并按此顺序调用对应的事件?
补充说明:无法将Children的类型改为List<EventClass>,因为需要指定部分子实例执行OnExecuteA,部分执行OnExecuteB;若改为List<(int,EventClass)>这类需要额外信息的类型会更繁琐,因此选择直接存储EventHandler委托。
解决方案
完全可以实现,核心思路是利用EventHandler委托的Target属性——因为你添加的都是EventClass实例的成员方法,所以handler.Target就是对应的EventClass对象,从中取出ExecuteOrder即可排序。
1. 排序代码
在需要执行事件前,对parent.Children进行排序:
// 按对应EventClass实例的ExecuteOrder升序排序 parent.Children = parent.Children .OrderBy(handler => ((EventClass)handler.Target).ExecuteOrder) .ToList();
2. 按顺序执行事件
排序后遍历列表调用每个委托即可:
// 模拟触发事件的sender和参数 object sender = null; EventArgs e = EventArgs.Empty; foreach (var handler in parent.Children) { handler.Invoke(sender, e); }
注意事项
- 如果场景中存在
handler.Target不是EventClass的情况(比如添加了静态方法或其他类的方法),需要加类型判断避免转换异常:parent.Children = parent.Children .Where(handler => handler.Target is EventClass) .OrderBy(handler => ((EventClass)handler.Target).ExecuteOrder) .ToList(); - 排序操作会修改原列表的顺序,如果需要保留原列表,可以创建新列表进行排序和执行。
内容的提问来源于stack exchange,提问作者Pikachu620
相关产品推荐
相关产品推荐

