// 10/12/2016 // Class: C# // Events: // Publisher Subscriber // - publishes events - subscribes to event // =============================== EXAMPLE CODE BELOW =============================== using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyCollections { //We inherit from ArrayList to create an array list which also //publishes an event. public class ArrayListWithEvent : System.Collections.ArrayList { ///////////////////////// //Publishing the event!!! ///////////////////////// public event EventHandler Changed; //The goal here is to wrap event "invocation" behavior. This is //important so that classes which inherit ArrayListWithEvent can //override this method with custom invocation behavior. protected virtual void OnChanged(EventArgs e) { //The variable "Changed" is an EventHandler. It's sort of a "collection" //of subscribers to the event. Changed != null means that we have subscribers; //Changed == null means we have no subscribers. if (Changed != null) { Changed(this, e); } } //Override Add method of array list, so we can fire event when user adds to list //OnChanged is how we fire the event. // //Note: EventArgs is a way to pass event data; for example, here we could pass a //string "add". Then, we could also override the Remove method of the ArrayList //so that it fires an event which passes a string "remove" to EventArgs. //Then, in the OnChanged method, we can handle these two cases differently. //In this example, we leave EventArgs empty. public override int Add(object value) { OnChanged(EventArgs.Empty); //This line here says "do what my parent (ArrayList) does". //i.e., we want Add to act the same as ArrayList, so we call //the original method. return base.Add(value); } } /////////////////////////// //Subscribing to the event! /////////////////////////// //"event listeners" are helper classes which encapsulate the //methods for subscribing to an event. //Typically, the constructor subscribes to the event, and also //a Detach() method is included, which unsubscribes from the event. public class ListChangedEventListener { private ArrayListWithEvent list; public ListChangedEventListener(ArrayListWithEvent inputList) { list = inputList; //This is the key statement: This subscribes the ListChanged method //to the event Changed. Remember, Changed is like a "collection" of events. //"+=" is used to add ListChanged to the Changed event handler. //Then, ListChanged will be called when Changed fires. list.Changed += ListChanged; } //The method ListChanged, which we are subscribing to Changed in the constructor of this class. //The method here must have this return type and parameters to match the Changed event; you can //use delegates to define a custom event handler with different return types and parameters, but //we used the default event handler when we published the event. public void ListChanged(object sender, EventArgs e) { Console.WriteLine("User has added to list."); } public void Detach() { //Remove ListChanged from Changed event handler list.Changed -= new ChangedEventHandler(ListChanged); //Delete the list so we can reuse the same listener instance, if we want. list = null; } } class Program { static void Main(string[] args) { //When we construct an object of type ArrayListWithEvent, it publishes the event. ArrayListWithEvent list1 = new ArrayListWithEvent(); //When we construct the listener object, it subscribes list1 to the event. ListChangedEventListener listener = new ListChangedEventListener(list1); list1.Add(6); list1.Add(7); //Unsubscribe. listener.Detach(); list1.Add(6); } } }