T B H P N

C# Delegates

Synopsis:

A delegate is a callable object that can be passed to, and returned from other functions. Delegates can refer to one or more methods, each with the same signature, and invoke them at some specified time. Delegates can bind to any lambda with the same signature, e.g., parameter sequence and return value.
Delegates are used primarily for two purposes:
  1. Implement publish-subscribe eventing:
    The publisher knows about some events that may happen in its own code. But, it doesn't know how to handle them. One or more subscribers need to know when one of those events happens, and know how to respond. The publisher aggregates a delegate for each event type, and makes them public. Subscribers use a publisher's delegate type to create a new instance of the delegate, referring to a subscriber event-handler method, and registers the new instance with the publisher. When an event occurs, the publisher invokes its delegate, which invokes, in-turn, each subscriber's event handler function.
  2. Bind to Lambdas to provide transport:
    Delegates can be bound to a lambda, of the same signature, i.e.:
      Action<string> act = (string s) => Console.Write("\n  {0}\n" s);    
    
    Action<T> is a delegate that accepts an argument of type T and has void return type. The instance act can now be passed to, or returned from, a function.
Here is demonstration code that uses both user defined and .Net defined delegates in a typical ways.

Code in File Delegates.cs

  /////////////////////////////////////////////////////////////////////
  // DelegateDemo.cs - basic delegates                               //
  //                                                                 //
  // Jim Fawcett, CSE681 - Software Modeling and Analysis, Fall 2017 //
  /////////////////////////////////////////////////////////////////////

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;

  namespace Delegates
  {
    public class TestDelegates
    {
      public delegate void MyDelegate();  // delegate type - could declare return type and argument types    
      public event MyDelegate myDel;      // delegate instance

      private static int Scount = 0;
      private int NScount = 0;

      public void nsMethod()
      {
        ++NScount;
        Console.Write("\n  Hello, I'm a  non-static method of TestDelegates");
        Console.Write("\n  my non-static NScount has value {0}", NScount);
      }
      public static void sMethod()
      {
        ++Scount;
        Console.Write("\n  Hi, I'm a static method of TestDelegates");
        Console.Write("\n  my static Scount has value {0}", Scount);
      }
      static void Main(string[] args)
      {
        Console.Write("\n  Demonstating Simple use of Delegates");
        Console.Write("\n ======================================");

        TestDelegates td = new TestDelegates();

        // building linked list of delegates declared in this class

        td.myDel += new MyDelegate(td.nsMethod);
        td.myDel += new MyDelegate(TestDelegates.sMethod);

        td.myDel.Invoke();
        Console.Write("\n");

        // System.Action delegate bound to lambda that uses captured data

        Action myAct;
        string msg = ".Net defined Action bound to lambda with this captured message";
        myAct = () => Console.Write("\n  {0}", msg);
        myAct += () => td.nsMethod();
        myAct.Invoke();
        Console.Write("\n");

        // System.Action delegate bound to lambda that uses passed argument

        Action<int> myIntAct;
        myIntAct = (int i) => Console.Write("\n  Action<int> passed value {0}", i);
        myIntAct.Invoke(3);
        Console.Write("\n\n");
      }
    }
  }

Delegates Output:

  
  Demonstating Simple use of Delegates
 ======================================
  Hello, I'm a  non-static method of TestDelegates
  my non-static NScount has value 1
  Hi, I'm a static method of TestDelegates
  my static Scount has value 1

  .Net defined Action bound to lambda with this captured message     
  Hello, I'm a  non-static method of TestDelegates
  my non-static NScount has value 2

  Action passed value 3

Press any key to continue . . .

Example Code:

CST strip