Introduction An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a mouse click, or it could be triggered by some other program logic. The object that raises the event is called the event sender. The object that captures the event and responds to it is called the event receiver. In event communication, the event sender class does not know which object or method will receive the events it raises. What is needed is an intermediary between the source and the receiver. The .NET Framework defines a special type that provides the functionality of a function pointer. A delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. While delegates have other uses, the discussion here focuses on the event handling functionality of delegates. Delegates are the basis for Events.A delegate can be instantiated by associating it either with a named or anonymous method. Let us see example on events and delegates Code: using System; namespace MyCollections { using System.Collections; // A delegate type for hooking up change notifications. public delegate void ChangedEventHandler(object sender, EventArgs e); // A class that works just like ArrayList, but sends event // notifications whenever the list changes. public class ListWithChangedEvent : ArrayList { // An event that clients can use to be notified whenever the // elements of the list change. public event ChangedEventHandler Changed; // Invoke the Changed event; called whenever list changes protected virtual void OnChanged(EventArgs e) { if (Changed != null) Changed(this, e); } // Override some of the methods that can change the list; // invoke event after each public override int Add(object value) { int i = base.Add(value); OnChanged(EventArgs.Empty); return i; } public override void Clear() { base.Clear(); OnChanged(EventArgs.Empty); } public override object this[int index] { set { base[index] = value; OnChanged(EventArgs.Empty); } } } } namespace TestEvents { using MyCollections; class EventListener { private ListWithChangedEvent List; public EventListener(ListWithChangedEvent list) { List = list; // Add "ListChanged" to the Changed event on "List". List.Changed += new ChangedEventHandler(ListChanged); } // This will be called whenever the list changes. private void ListChanged(object sender, EventArgs e) { Console.WriteLine("This is called when the event fires."); } public void Detach() { // Detach the event and delete the list List.Changed -= new ChangedEventHandler(ListChanged); List = null; } } class Test { // Test the ListWithChangedEvent class. public static void Main() { // Create a new list. ListWithChangedEvent list = new ListWithChangedEvent(); // Create a class that listens to the list's change event. EventListener listener = new EventListener(list); // Add and remove items from the list. list.Add("item 1"); list.Clear(); listener.Detach(); } } } Lets us see an example on Delegates. For use with named methods, the delegate must be instantiated with a method that has an acceptable signature. Code: using System; // Declare delegate -- defines required signature: delegate void SampleDelegate(string message); class MainClass { // Regular method that matches signature: static void SampleDelegateMethod(string message) { Console.WriteLine(message); } static void Main() { // Instantiate delegate with named method: SampleDelegate d1 = SampleDelegateMethod; // Instantiate delegate with anonymous method: SampleDelegate d2 = delegate(string message) { Console.WriteLine(message); }; // Invoke delegate d1: d1("Hello"); // Invoke delegate d2: d2(" World"); } }