I was looking through the C# Language Specification and bumped into the following explanations about Events section 1.7.5:


For a simple event declaration such as

public event EventHandler Click;

the compiler automatically provides the implementation underlying the += and -= operators.

An implementer who wants more control can get it by explicitly providing add and remove accessors. For example, the Button class could be rewritten as follows:

public class Button
{
            private EventHandler handler;

            public event EventHandler Click {

                  add { handler += value; }

                  remove { handler -= value; }
            }
}

This change has no effect on client code, but allows the Button class more implementation flexibility. For example, the event handler for Click need not be represented by a field.


After reading this, I was like...cool!  Let me play around and see what I can come up with.  Like usual, I came up with the following code snippet:

using System;
namespace EventHandlerTest
{
    /// 
    /// Summary description for HandlerCaller.
    /// 
    class HandlerCaller
    {
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main(string[] args)
        {
            HandlerHost hh = new HandlerHost();
            //Handlers for the 'main' events
            EventHandler task1 = new EventHandler(HandlerCaller.HandleTask1);
            EventHandler task2 = new EventHandler(HandlerCaller.HandleTask2);
            //Add the handlers!
            for(int i=0; i<10; i++)
                hh.SomeEvent += (i%2 == 0) ? task1 : task2;
            
            Console.WriteLine();
            //Invoke the method
            hh.DoTask();
            Console.WriteLine();
            //Remove the handlers!
            for(int i=0; i<10; i++)
                hh.SomeEvent -= (i%2 == 0) ? task1 : task2;
            Console.WriteLine("Hit  to continue...");
            Console.ReadLine();
        }
        // Delegate #1 for the SomeEvent event
        public static void HandleTask1(object sender, EventArgs e)
        {
            Console.WriteLine("From HandleTask1!!");
        }
        // Delegate #2 for the SomeEvent event
        public static void HandleTask2(object sender, EventArgs e)
        {
            Console.WriteLine("From HandleTask2!!");
        }
    }
    class HandlerHost
    {
        public HandlerHost()
        {
            // Register the events when they are done
            EventHandlerAdded += new EventHandler(EventAdded);
            EventHandlerRemoved += new EventHandler(EventRemoved);
        }
        EventHandler RegisteredHandlers;
        event EventHandler EventHandlerAdded;
        event EventHandler EventHandlerRemoved;
        public event EventHandler SomeEvent
        {
            add
            {
                // We don't add the event here
                // will handle this on the delegate
                if(EventHandlerAdded != null)
                    EventHandlerAdded(value,null);
            }
            remove
            {
                // We don't remove the event here
                // will handle this on the delegate
                if(EventHandlerRemoved != null)
                    EventHandlerRemoved(value,null);
            }
        }
        // Internal deleage for adding an event to class internal event list
        void EventAdded(object sender, EventArgs e)
        {
            EventHandler eh = sender as EventHandler;
            // Add the handler to the list!
            RegisteredHandlers = Delegate.Combine(RegisteredHandlers,eh) as EventHandler;
            // Report the console
            Console.WriteLine("Added event mapped to method: {0}.{1}", eh.Method.DeclaringType.Name, eh.Method.Name);
        }
        // Internal delegate for removing an event from the class internal event list
        void EventRemoved(object sender, EventArgs e)
        {
            EventHandler eh = sender as EventHandler;
            // Remove the handler from the list!
            RegisteredHandlers = Delegate.Remove(RegisteredHandlers,eh) as EventHandler;
            // Report the console
            Console.WriteLine("Removed event that was mapped to method: {0}.{1}", eh.Method.DeclaringType.Name, eh.Method.Name);
        }
        public void DoTask()
        {
            // We cannot call the event directly
            // (like above since we are implementing the add and remove sections)
            if(RegisteredHandlers != null)
                RegisteredHandlers(this,null);
        }
    }
}

 

Happy coding!