array of events in C#?

前端 未结 4 1775
忘掉有多难
忘掉有多难 2020-12-20 18:04

basically:

public delegate void RecvCommandHandler (ChatApplication sender, byte[] content);
event RecvCommandHandler[] commands = new RecvCommandHandler[255         


        
相关标签:
4条回答
  • 2020-12-20 18:41

    You could create an array of a class with operator overloading to simulate the behavior you are interested in...

    public delegate void EventDelegate(EventData kEvent);
    
    public class EventElement
    {
        protected event EventDelegate eventdelegate;
    
        public void Dispatch(EventData kEvent)
        {
            if (eventdelegate != null)
            {
                eventdelegate(kEvent);
            }
        }
    
        public static EventElement operator +(EventElement kElement, EventDelegate kDelegate)
        {
            kElement.eventdelegate += kDelegate;
            return kElement;
        }
    
        public static EventElement operator -(EventElement kElement, EventDelegate kDelegate)
        {
            kElement.eventdelegate -= kDelegate;
            return kElement;
        }
    }
    
    public EventElement[] commands = new EventElement[255];
    
    commands[100] += OnWhatever;
    commands[100].Dispatch(new EventData());
    commands[100] -= OnWhatever;
    
    0 讨论(0)
  • 2020-12-20 18:48

    There's really no concept of an array of events - it's like talking about an array of properties. Events are really just methods which let you subscribe and unsubscribe handlers. If you need to be able to do this by index, I suggest you just have a pair of methods. (AddCommandHandler(int, RecvCommandHandler) and RemoveCommandHandler(int, RecvCommandHandler)). That won't support the normal event handling syntactic sugar, of course, but I don't see that there's a lot of alternative.

    0 讨论(0)
  • 2020-12-20 18:48

    The other option is to specify and index in the delegate prototype and have one event handler that "delegates" to the others, e.g.:

    public delegate void RecvCommandHandler (int id, ChatApplication sender, byte[] content);
    
    // ...
    
    private RecvCommandHandler[] internalhandlers;
    
    public void MyCommandHandler(int id, ChatApplication sender, byte[] content)
    {
        internalHandlers[id](id, sender, content);
    }
    
    0 讨论(0)
  • 2020-12-20 18:53

    I was just looking for the same answer, however my class is also event sender for WPF, so it should look as much as normal C#/WPF event sender class. So I simply added this:

    To sender:

    • enum with properties name -- this is lame workaround for lack of nameof
    • one additional method to record requests

    To receiver:

    • request event for given enum

    The code, sender:

        public enum Properties
        {
            NetworkFileName,
            DatasetFileName,
            LearningWatch
        }
    
        private string network_filename;
        public string NetworkFileName 
        {
            get { return network_filename; }
            private set 
            {
                if (network_filename != value)
                {
                    network_filename = value;
                    OnPropertyChanged(Properties.NetworkFileName.ToString());
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    
        public void OnChange(Properties prop, Action<object, PropertyChangedEventArgs> action)
        {
            PropertyChanged += new PropertyChangedEventHandler((obj, args) => { if (args.PropertyName == prop.ToString()) action(obj, args); });
        }
    

    And to the receiver:

        private void OnNetworkLoaded(object sender, PropertyChangedEventArgs e)
        {
            SetTitle();
        }
    
            ...
            ExpManager.OnChange(ExperimentManager.Properties.DatasetFileName, OnDatasetLoaded);
    

    It is still ugly, but at least:

    • I don't have to deal with "ifs" in receiver
    • I can easily create multiple event handlers
    • it is compatible with WPF
    • no magic strings (I hate those)

    Disadvantage:

    • obsfuscation ruins this (but I have special class for that case, this project is just for me, so no problem here)
    0 讨论(0)
提交回复
热议问题