Click here to Skip to main content
11,490,282 members (53,183 online)
Click here to Skip to main content

Delegates and Types of Delegates in C#

, 13 May 2014 CPOL 58.5K 452 51
Rate this:
Please Sign up or sign in to vote.
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().

    /// 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().

    /// <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.

    /// <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.

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.

    /// <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.

/// <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)

Share

About the Author

Bhim B Thapa
Software Developer APTA
United States United States
No Biography provided

Comments and Discussions

 
QuestionGreat artical Pin
RhishikeshLathe16-Apr-15 0:24
professionalRhishikeshLathe16-Apr-15 0:24 
AnswerRe: Great artical Pin
Bhim B Thapa28-Apr-15 9:31
professionalBhim B Thapa28-Apr-15 9:31 
GeneralMy vote of 5 Pin
Bilal Fazlani29-Dec-14 23:13
memberBilal Fazlani29-Dec-14 23:13 
GeneralRe: My vote of 5 Pin
Bhim B Thapa30-Dec-14 3:02
professionalBhim B Thapa30-Dec-14 3:02 
QuestionMy vote of 5 Pin
Member 1042270617-Sep-14 4:31
memberMember 1042270617-Sep-14 4:31 
AnswerRe: My vote of 5 Pin
Bhim B Thapa17-Sep-14 4:36
professionalBhim B Thapa17-Sep-14 4:36 
GeneralMy vote of 3 Pin
Paulo Zemek27-May-14 9:54
professionalPaulo Zemek27-May-14 9:54 
GeneralRe: My vote of 3 Pin
Bhim B Thapa27-May-14 10:36
professionalBhim B Thapa27-May-14 10:36 
QuestionGeneric delegate Pin
Paulo Zemek27-May-14 9:50
professionalPaulo Zemek27-May-14 9:50 
GeneralMy vote of 5 Pin
JCahyaatnttearjee16-May-14 1:00
memberJCahyaatnttearjee16-May-14 1:00 
QuestionReally an interesting article! Pin
Member 1082021814-May-14 23:47
memberMember 1082021814-May-14 23:47 
SuggestionYou fell into the trap MS prepared for us... Pin
alex2001_ts14-May-14 8:46
memberalex2001_ts14-May-14 8:46 
GeneralRe: You fell into the trap MS prepared for us... Pin
Bhim B Thapa14-May-14 10:48
professionalBhim B Thapa14-May-14 10:48 
GeneralMy vote of 5 Pin
mrnfalpe14-May-14 7:52
membermrnfalpe14-May-14 7:52 
QuestionSingle Delegate Pin
FatCatProgrammer14-May-14 6:10
memberFatCatProgrammer14-May-14 6:10 
AnswerRe: Single Delegate Pin
Bhim B Thapa14-May-14 7:37
professionalBhim B Thapa14-May-14 7:37 
GeneralRe: Single Delegate Pin
FatCatProgrammer14-May-14 8:54
memberFatCatProgrammer14-May-14 8:54 
AnswerRe: Single Delegate Pin
Bhim B Thapa14-May-14 10:49
professionalBhim B Thapa14-May-14 10:49 
GeneralMy vote of 5 Pin
Thiago Romam14-May-14 2:43
professionalThiago Romam14-May-14 2:43 
GeneralRe: My vote of 5 Pin
Bhim B Thapa14-May-14 2:55
professionalBhim B Thapa14-May-14 2:55 
GeneralNice article Pin
ashwani4u14-May-14 1:43
memberashwani4u14-May-14 1:43 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun13-May-14 21:30
memberHumayun Kabir Mamun13-May-14 21:30 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150520.1 | Last Updated 13 May 2014
Article Copyright 2014 by Bhim B Thapa
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid