Web Design that taps into the haromny and vision of your dreams.

C# Event Handling and Delegates

Ultimate guide to c# event handling

Written By on in C#

771 words, estimated reading time 4 minutes.

Delegates allow your code to dynamically change the method that it calls. This allows a method to change, based on the code that invokes it. Events are delegate methods that are invoked on a certain condition.

Advanced C# Programming Series
  1. C# Advanced Data Types
  2. Using C# Properties and Indexers
  3. C# Event Handling and Delegates
  4. Method Overloading and Overriding in C#
  5. C# Class Abstraction and Encapsulation
  6. C# Aggregation and Advanced Scope Techniques
  7. Polymorphism in C#
  8. Boxing and Unboxing Value Types in C#
  9. C# Operator Overloading
  10. Creating Multi-Threading Applications with C#
  11. Unsafe Code Execution in Microsoft .Net

Delegates

A delegate type is a reference type, which allows an indirect call to a method. It holds a pointer to a method declared elsewhere, and when the delegate is invoked, it, in turn, invokes the method it points to. Delegate methods are very similar to C++ function pointers, except that a delegate type can point to multiple methods.

In this example we call an OutputText method with a string and an output method and the delegate type, Write, sorts out whether to write to a file or write to the screen.

using System
using System.IO
 
public class Program
{
 
  // Define our delegate type
  public delegate void Write(string theText);
 
  // Method for output to screen
  public static void OutputToScreen(string theText)
  {
    Console.WriteLine(theText);
  }
 
  // Method to output to file
  public static void WriteToFile(string theText)
  {
    StreamWriter fileWriter = File.CreateText("c:/delegate-demo.txt");
    fileWriter.WriteLine(theText);
    fileWriter.Flush();
    fileWriter.Close();
  }
 
  public static void Main()
  {
    // Assign a method to a delegate
    Write toFile = new Write(WriteToFile);
    Write toScreen = new Write(OutputToScreen);
 
    Display("This is a delegate demo", toFile);
    Display("This is a delegate demo", toScreen);
  }
 
  public static void Display(string theText, Write outputMethod)
  {
    outputMethod(theText);
  }
}

A bit of a long example, but it is good to illustrate how the delegate can be used to determine the method to call for outputting the text, either to file or to screen.

We start off by defining the delegate in the same way, as we would start to declare a method. We use the delegate keyword to mark the method, and because there are no implementations we terminate the statement with a semi-colon.

Next, we define two methods, which could have the delegate pointing to. They must have the same method signature as the delegate defined above.

In the main method we assign an instance of the delegate type to each of our test output methods, then we call a generic Display method with the text to process and the display method.

This Display method invokes the output message with the text passed in.

Multicast Delegates

A multicast delegate can call to multiple methods using the += operator.

  public static void Main()
  {
    // Assign a method to a delegate
    Write toFile = new Write(WriteToFile);
    toFile += new Write(OutputToScreen);

In this example, when toFile is invoked, both WriteToFile and OutputToScreen will be called.

You can remove delegates using the -= operator:

  public static void Main()
  {
    // Assign a method to a delegate
    Write toFile = new Write(WriteToFile);
    toFile += new Write(OutputToScreen);
    toFile -= WriteToFile;
 

When invoking toFile, it will only call OutputToScreen now.

Events

Events are similar to delegates, except that a delegate has to be called, whereas an event is a response to a condition. Examples of common events are Button_Click, Page_Load and Mouse_Over. Events can also be multicast, assigned to and removed in the same way as a multicast delegate.

this.Load += new System.EventHandler(this.Form1_Load);

The concept of events is based on a subscription-notification model. Any class must be able to "subscribe" to an event and receive a "notification" whenever the events occur. When a class subscribes to an event, it declares its interest in the event, and when it receives the notification it has its delegate methods run.

In the following example shows how testClass2 subscribes to an event issued by testClass1.

  • testClass1 issues events. It has a multicast delegate, eventD.
  • testClass2 subscribes to the event with its method eventHandler by adding a reference to eventD.
  • When testClass1 issues an event it invokes eventD, which causes eventHandler to fire.

Creating Events

You can create events in your code in a similar way that properties are declared - by defining a public event and a protected method.

public class Program
{
  public delegate void EventDelegate(object sender, EventArgs args);
  public event EventDelegate testEvent;
 
  protected virtual void onTestEvent(EventArgs args)
  {
    if (testEvent != null)
      testEvent(this, args)
  }
}

You should always check that the delegate is not null before calling it, as you could end up with exceptions being thrown.

Events and Inheritance

If your class inherits from a class, which already issues or responds to events, you can intercept these actions by overriding the method used to raise it.

protected override void onMyEvent(EventArgs args)
{
  Console.WriteLine("The Event Stops Here");
}

This will also prevent any "subscriptions" from receiving their "notifications". If you wish subscribers to continue to receive the notifications then simply call the base event method.

protected override void onMyEvent(EventArgs args)
{
  Console.WriteLine("The Event Passed Here and Carried on");
  base.onMyEvent(args);
}

Last updated on: Friday 23rd June 2017

 

Comments
Robert V

Robert V

Very nice explanation of delegates, makes sense to me finally.

Reply to Robert V

 

Leave a Reply

Your email address will not be published.





If you find something abusive or that does not comply with our terms or guidelines please flag it as inappropriate.

Copyright © 2001-2018 Tim Trott, all rights reserved. Web Design by Azulia Designs

This web page is licensed for your personal, private, non-commercial use only.

Disclaimer, Privacy & LegalSitemapContact Me