C# Delegate

Description

A delegate is a type for method.

A delegate type defines a protocol to which the caller and target will conform, comprising parameter types and a return type.

A delegate instance is an object that refers to one (or more) target methods conforming to that protocol.

Syntax

A delegate is declared using the keyword delegate. The general form of a delegate declaration:

delegate ret-type name(parameter-list);
  • ret-type is return type.
  • The parameters required by the methods are specified in the parameter-list.

A delegate can call only methods whose return type and parameter list match those specified by the delegate's declaration.

All delegates are classes that are implicitly derived from System.Delegate.

Example

The following code defines a delegate.

delegate void Printer(int i);

Here the Printer is the name of the delegate. It is like the name of the class or a struct. Later we can use it as a type.


using System;// w w  w.ja v  a2s.  c om

delegate void Printer(int i);
class Test
{
    static void consolePrinter(int i)
    {
        Console.WriteLine(i);
    }
    static void Main()
    {

        Printer p = consolePrinter;
        p(33);

    }
}

The output:

In the code above we define a variable p whose type is Printer. delegate defines a way we should follow to create methods. Then later we can use the delegate type to reference the methods with the same form. Printer delegate requires that the type of method should take single int type as input and return void.

Example 2

A delegate variable is assigned a method dynamically. This is useful for writing plug-in methods.

In this example, we have a utility method named Transform that applies a transform to each element in an integer array.

The Transform method has a delegate parameter, for specifying a plug-in transform.


using System;/*  www  . j a v a 2s .  c  o  m*/

public delegate int Transformer (int x);

class Util{
 public static void Transform (int[] values, Transformer t){
   for (int i = 0; i < values.Length; i++)
     values[i] = t (values[i]);
 }
}

class Test{
 static void Main()
 {
   int[] values = { 1, 2, 3 };
   Util.Transform (values, Square);      
   foreach (int i in values)
     Console.Write (i + "  ");
 }

 static int Square (int x) { return x * x; }
}

The code above generates the following result.

Instance Versus Static Method Targets

When a delegate object is assigned to an instance method, the delegate object must maintain a reference not only to the method, but also to the instance to which the method belongs.

The System.Delegate class's Target property represents this instance. It is null for a delegate referencing a static method.

For example:


/*ww  w  .j  a  v  a  2  s  .  c  om*/
using System;

public delegate void ProgressReporter (int percentComplete);

class Test{
  static void Main(){
    X x = new X();
    ProgressReporter p = x.InstanceProgress;
    p(99);                                 
    Console.WriteLine (p.Target == x);     
    Console.WriteLine (p.Method);          
  }
}
class X {
  public void InstanceProgress (int percentComplete)
  {
    Console.WriteLine (percentComplete);
  }
}

The code above generates the following result.

Example 3

Two delegate variables aren't equal.


using System;/*from   www  .j  av  a 2s.  c o m*/
delegate void Printer();
delegate void Display();

class Test
{
    static void consolePrinter()
    {
        Console.WriteLine("hi");
    }
    static void Main()
    {
        Printer p = consolePrinter;

        Display d = p;

    }
}

Compile time error.

Example 4


using System;//  www  .j  a  v a2 s . co m

public delegate double ComputeDelegate( double x,double y );

public class MyClass
{
    public MyClass( ) {
    }

    public double Add( double x, double y ) {
        double result = x+y;
        Console.WriteLine( "InstanceResults: {0}", result );
        return result;
    }

    public static double Subtract( double x,double y ) {
        double result = x - y;
        Console.WriteLine( "StaticResult: {0}", result );
        return result;
    }

    private double factor;
}

public class MainClass
{
    static void Main() {
        MyClass proc1 = new MyClass( );
        MyClass proc2 = new MyClass( );

        ComputeDelegate[] delegates = new ComputeDelegate[] {
            new ComputeDelegate( proc1.Add ),
            new ComputeDelegate( proc2.Add ),
            new ComputeDelegate( MyClass.Subtract )
        };

        ComputeDelegate chained = (ComputeDelegate) Delegate.Combine( delegates );

        double combined = chained( 4, 5 );
        
        Console.WriteLine( "Output: {0}", combined );
    }
}

The code above generates the following result.

Example 5


using System;//ww  w  . j  a  v  a 2  s  .  c  o m

public delegate void MyDeleage();

public class MainClass
{
    public static MyDeleage[] CreateDelegates() {
        MyDeleage[] delegates = new MyDeleage[3];
        
        for( int i = 0; i < 3; ++i ) {
            delegates[i] = delegate {
                Console.WriteLine( "Hi" ); 
            };
        }
        return delegates;
    }

    static void Main() {
        MyDeleage[] delegates = CreateDelegates();
        for( int i = 0; i < 3; ++i ) {
            delegates[i]();
        }
    }
}

The code above generates the following result.

Example 6


using System;//ww  w  .jav  a2s  .  c o  m
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;

delegate void FooBar();

public class MainClass
{
    static void Invoke3Times(FooBar d)
    {
        d(); d(); d();
    }

   public static void Main(){
        int i = 0;
        Invoke3Times(delegate { i++; });
        Console.WriteLine(i);

   }

}

The code above generates the following result.





















Home »
  C# Tutorial »
    Custom Types »




C# Class
C# Struct
C# Interface
C# Inheritance
C# Namespace
C# Object
C# Delegate
C# Lambda
C# Event
C# Enum
C# Attribute
C# Generics
C# Preprocessor