Click here to Skip to main content
15,883,915 members
Articles / Programming Languages / C#

Delegates and Types of Delegates in C#

Rate me:
Please Sign up or sign in to vote.
4.65/5 (46 votes)
13 May 2014CPOL3 min read 307.5K   1.2K   75   28
Concepts of Delegates and Types of Delegate in C#

Table Of Contents

Why Delegates?

Delegates are used in the following cases:

  • Delegates can be used to handle(call/invoke) multiple methods on a single event.
  • Delegates can be used to define callback(asynchronous) methods.
  • Delegates can be used for decoupling and implementing generic behaviors.
  • Delegates can be invoked method at runtime.
  • Delegates can be used in LINQ for parsing the ExpressionTree.
  • Delegates can be used in different Design Pattern.

Definition

A delegate(known as function pointer in C/C++) is a references type that invokes single/multiple method(s) through the delegate instance. It holds a reference of the methods. Delegate types are sealed and immutable type.

Types of Delegates

There are three types of delegates that can be used in C#.

  • Single Delegate
  • Multicast Delegate
  • Generic Delegate

Single Delegate

Single delegate can be used to invoke a single method. In the given source code example, a delegate CalculateSimpleInterest invokes a method getTotalInterest().

C++
    /// Sample example of simple delegate
    /// 
    class Program
    {
       // Declare a delegate
        delegate double CalculateSimpleInterest(double p, double t, double r);
        static CalculateSimpleInterest SI = getTotalInterest;

        static void Main(string[] args)
        {
            double totalInterest;
            //Method I : Invocation of simple delegate by using Invoke keyword
            totalInterest = SI.Invoke(120, 1, 3.25);
            Console.WriteLine("Total Interest of $120 
            in a year at rate of 3.25% APR is {0}",totalInterest);

            //Method II : Invocation of simple delegate by passing method name
            CalculateSimpleInterest D = new CalculateSimpleInterest(getTotalInterest);
            totalInterest = D(120, 1, 3.25);
            Console.WriteLine("Total Interest of $120 
            in a year at rate of 3.25% APR is {0}", totalInterest);
            Console.ReadKey();
        }
//Creating methods which will be assigned to delegate object
        /// <summary>
        /// Gets the total interest.
        /// </summary>
        /// <param name="p" />The Principal.
        /// <param name="t" />The Time.
        /// <param name="r" />The Rate.
        /// <returns>Total Interest
        static double getTotalInterest(double p, double t, double r)
        {
            return (p * t * r) / 100;
        }
    }

Multicast Delegate

Multicast delegate can be used to invoke the multiple methods. The delegate instance can do multicasting (adding new method on existing delegate instance) using the + operator and operator can be used to remove a method from a delegate instance. All methods will invoke in sequence as they are assigned.

In the given source code example, a delegate instance dObjSI invokes the methods getTotalInterest(), getInterestRatePerYear() and getInterestTimeSpan().

C++
/// <summary>
/// Sample example of multicast delegate
///
class Program
{
   // Declare a delegate
    delegate double CalculateSimpleInterest(double para1, double para2, double para3);
    static CalculateSimpleInterest dObjSI = getTotalInterest;

    static void Main(string[] args)
    {
        double SI;
        //Calculating simple interest
        SI = dObjSI.Invoke(120, 1, 3.25);
        //using multicast delegate by invoking method getInterestRatePerYear()
        dObjSI += new CalculateSimpleInterest(getInterestRatePerYear);
        double Rate=dObjSI.Invoke(SI, 120, 1);
        Console.WriteLine("APR rate is {0}", Rate);
        //using multicast delegate by invoking method getInterestTimeSpan()
        dObjSI += new CalculateSimpleInterest(getInterestTimeSpan);
        double TimeSpan = dObjSI.Invoke(SI, 120, 3.25);
        Console.WriteLine("Time Span is {0}", TimeSpan);


        Console.ReadKey();
    }

    /// <summary>
    /// Gets the total interest.
    /// </summary>
    /// <param name="p" />The Principal.
    /// <param name="t" />The Time.
    /// <param name="r" />The Rate.
    /// <returns>Total Interest
    static double getTotalInterest(double p, double t, double r)
    {
        return (p * t * r) / 100;
    }
    /// <summary>
    /// Gets the interest rate per year.
    /// </summary>
    /// <param name="SI" />The Simple Interest.
    /// <param name="p" />The Principal.
    /// <param name="t" />The Time.
    /// <returns>Interest rate per year
    static double getInterestRatePerYear(double SI, double p, double t)
    {
        return (SI * 100)/(p*t);
    }
    /// <summary>
    /// Gets the interest time span.
    /// </summary>
    /// <param name="SI" />The Simple Interest.
    /// <param name="p" />The Principal.
    /// <param name="r" />The Rate.
    /// <returns>Interest time span
    static double getInterestTimeSpan(double SI, double p, double r)
    {
        return (SI * 100) / (p * r);
    }
}

Generic Delegate

Generic Delegate was introduced in .NET 3.5 that don't require to define the delegate instance in order to invoke the methods.

There are three types of generic delegates:

  • Func
  • Action
  • Predicate

Generic Delegate: Func

The Func delegate defines a method that can be called on arguments and returns a result. In the given code example, delegate Func<interest,double> is defined with Interest type as argument and double as return type.

C++
    /// <summary>
    /// Sample example of generic delegate
    /// 
    class Program
    {
       // Declare a delegate
        delegate double CalculateSimpleInterest(double para1, double para2, double para3);
        static CalculateSimpleInterest dObjSI = getTotalInterest;

        static void Main(string[] args)
        {
           double SI;
            //Declare a generic Func delegate
            Func<interest,double> calcSI = SIObj =>(SIObj.P*SIObj.T*SIObj.R)/100;
            Interest obj = new Interest();
            obj.P = 120; obj.T = 1; obj.R = 3.25;
            // Consuming delegate
            SI = calcSI(obj);
            Console.WriteLine("Total Interest of $120 in a year at rate of 3.25% APR is {0}", SI);
            Console.ReadKey();
        }       
    }
    class Interest
    {
        public double P { get; set; }
        public double T { get; set; }
        public double R { get; set; }
    }
</interest,double>

Generic Delegate: Action

The Action delegate defines a method that can be called on arguments but does not return a result. In the given code example, delegate Action<string> is defined with string as argument.

C++
Action<string> MyAction = y => Console.Write(y);
            MyAction("Hello");
            Console.ReadKey();

Generic Delegate: Predicate

The Predicate delegate defines a method that can be called on arguments and always returns Boolean type result. In the given code example, delegate Predicate<string> checkValidDate is defined with string type as argument and returns bool type.

C++
    /// <summary>
    /// Sample example of generic delegate: Predicate
    /// 
    class Program
    {
        static void Main(string[] args)
        {
            string date="05/12/20143";
            Predicate<string> checkValidDate = d => IsDate(d) ;
            if (checkValidDate(date))
            {
                Console.WriteLine("Valid Date");
            }
            else
            {
                Console.WriteLine("Invalid Date");
            }
            Console.ReadKey();            
        }
         private static bool IsDate(string date)
         {
             DateTime dt;
             return DateTime.TryParse(date,out dt);
         }

    }
</string>

Expression Tree

Expression trees allow you to build code dynamically at runtime instead of statically typing it in the IDE and using a compiler. Expression Trees use generic delegates to create and parse the expressions.

Expression trees are used in the following cases:

  • Expression trees can be used to create LINQ to SQL and EF to SQL.
  • Expression trees can be used for ASP.NET MVC's HTML extensions.
  • Expression trees can be used to determine the selected property or field in MVC.

In the given code example, a expression (3+5)-(4-2) is divided into three expressions as Exp1 for (3+5), Exp2 for (4-2) and Exp3 for adding Exp1 and Exp2. The expression Expression.Lambda<func<int>>(resultexp).compile()() uses Func generic delegate to parse the expressions.

C++
/// <summary>
    /// Sample example of Expression Tree
    /// 
    class Program
    {
        static void Main(string[] args)
        {
            //Express tree (3+5)-(4-2)
            //3+5
            BinaryExpression Exp1 = Expression.MakeBinary(ExpressionType.Add, Expression.Constant(3),
                Expression.Constant(5));
            //4-2
            BinaryExpression Exp2 = Expression.MakeBinary(ExpressionType.Subtract, Expression.Constant(4),
                Expression.Constant(2));
           // (3+5)-(4-2)
            BinaryExpression resultExp = Expression.MakeBinary(ExpressionType.Subtract, Exp1, Exp2);
            //this stmt will create a delegates by parsing the expression three
            int result = Expression.Lambda<func<int>>
            (resultexp).compile()(); console.writeline("result="{0}",">

Difference Between Each Type of Generic Delegate

Func ActionPredicate
Arguments Yes Yes Yes
Returns Yes No Boolean Type Only

History

  • 13th May, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer APTA
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Emerald Lwyn25-Sep-16 21:15
professionalEmerald Lwyn25-Sep-16 21:15 
Generalcomment Pin
Member 12452061-Vishal13-Sep-16 8:30
Member 12452061-Vishal13-Sep-16 8:30 
Good article. I learnt the basics on delegates. But still I have a confusion in it. It lacks something.I
GeneralRe: comment Pin
Bhim B Thapa23-Jan-17 4:54
professionalBhim B Thapa23-Jan-17 4:54 
GeneralMy vote of 5 Pin
Pratik Bhuva29-Jun-15 4:33
professionalPratik Bhuva29-Jun-15 4:33 
GeneralRe: My vote of 5 Pin
Bhim B Thapa29-Jun-15 5:35
professionalBhim B Thapa29-Jun-15 5:35 
GeneralRe: My vote of 5 Pin
Bhim B Thapa23-Jan-17 4:54
professionalBhim B Thapa23-Jan-17 4:54 
QuestionGreat artical Pin
RhishikeshLathe15-Apr-15 23:24
professionalRhishikeshLathe15-Apr-15 23:24 
AnswerRe: Great artical Pin
Bhim B Thapa28-Apr-15 8:31
professionalBhim B Thapa28-Apr-15 8:31 
GeneralMy vote of 5 Pin
Bilal Fazlani29-Dec-14 22:13
Bilal Fazlani29-Dec-14 22:13 
GeneralRe: My vote of 5 Pin
Bhim B Thapa30-Dec-14 2:02
professionalBhim B Thapa30-Dec-14 2:02 
QuestionMy vote of 5 Pin
Member 1042270617-Sep-14 3:31
Member 1042270617-Sep-14 3:31 
AnswerRe: My vote of 5 Pin
Bhim B Thapa17-Sep-14 3:36
professionalBhim B Thapa17-Sep-14 3:36 
GeneralMy vote of 3 Pin
Paulo Zemek27-May-14 8:54
mvaPaulo Zemek27-May-14 8:54 
GeneralRe: My vote of 3 Pin
Bhim B Thapa27-May-14 9:36
professionalBhim B Thapa27-May-14 9:36 
QuestionGeneric delegate Pin
Paulo Zemek27-May-14 8:50
mvaPaulo Zemek27-May-14 8:50 
GeneralMy vote of 5 Pin
JayantaChatterjee16-May-14 0:00
professionalJayantaChatterjee16-May-14 0:00 
QuestionReally an interesting article! Pin
Member 1082021814-May-14 22:47
Member 1082021814-May-14 22:47 
SuggestionYou fell into the trap MS prepared for us... Pin
alex2001_ts14-May-14 7:46
professionalalex2001_ts14-May-14 7:46 
GeneralRe: You fell into the trap MS prepared for us... Pin
Bhim B Thapa14-May-14 9:48
professionalBhim B Thapa14-May-14 9:48 
GeneralMy vote of 5 Pin
marianafp14-May-14 6:52
professionalmarianafp14-May-14 6:52 
QuestionSingle Delegate Pin
FatCatProgrammer14-May-14 5:10
FatCatProgrammer14-May-14 5:10 
AnswerRe: Single Delegate Pin
Bhim B Thapa14-May-14 6:37
professionalBhim B Thapa14-May-14 6:37 
GeneralRe: Single Delegate Pin
FatCatProgrammer14-May-14 7:54
FatCatProgrammer14-May-14 7:54 
AnswerRe: Single Delegate Pin
Bhim B Thapa14-May-14 9:49
professionalBhim B Thapa14-May-14 9:49 
GeneralMy vote of 5 Pin
Thiago Romam14-May-14 1:43
professionalThiago Romam14-May-14 1:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.