Home > database >  Is it possible to sort a list of events?
Is it possible to sort a list of events?

Time:07-25

Suppose I have a class like the below:

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...
    }
}

And generate some EventClass like the following:

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()));
    //I didn't add it in order because this part is actually executed throughout 
    //different parts of my project, so I wouldn't know which one is added first, 
    //hence the disordered addition to simulating it.
}

So my question is, is it possible to sort the list back to {child1,child2,child3,child4,child5} and invoke their events in order?

PS. I can't set the Children's type to List<EventClass> because just like you saw above, I want some of the children to execute OnExecuteA and some to execute OnExecuteB, and I don't how to specify it without any extra information. Such as List<(int,EventClass)> Children and do something like

foreach((int,EventClass) c in Children)
{
    if(c.Item1 == 0) c.OnExecuteA(null,null);
    else c.OnExecuteB(null,null);
}

That's why I think it's better to just set the Children as a list of delegates and just add either OnExecuteA or OnExecuteB to it.

CodePudding user response:

As I said in the comments, it's probably better to have a List<EventClass> instead, but if you must do it this way, you can sort the delegates using the Target property after casting it to the correct type as follows:

parent.Children = parent.Children.OrderBy(d => ((EventClass)d.Target).ExecuteOrder).ToList();

You probably could also create an IComparer so that you can pass it to parent.Children.Sort(), but you might need to create a custom event because it wouldn't be a good idea to just create an IComparer<EventHandler> and expect any arbitrary EventHandler delegate's Target to be an EventClass instance.

  • Related