Monday, April 11, 2011

Action vs Func vs Predicate delegates

If you are working with .Net 4.0, you must have come across tailored-made delegates like Action, Func or Predicate many times. Today I shall discuss about them and explain how they can be useful in your daily coding practices.
Action delegate: Action delegate is an inbuilt delegate who can encapsulate any function that takes any type as input and returns nothing (void). If you see the metadata, Action delegate is nothing but

  public delegate void Action<in T>(T obj);

Example: Let say I want to encapsulate a function which prints the string input on console and which has return type void.

Approach 1:

 class Program
    {
        public delegate void myActionDel(string s);

        static void Main(string[] args)
        {
            myActionDel del = WriteToConsole;
            del("delegate works");
            Console.Read();
        }

        public static void WriteToConsole(string s)
        {
            Console.WriteLine(s);
        }
    }

What I am doing here is defining a delegate which can takes a string input and returns void. I am wrappping a function "WriteToConsole" of same signature as my delegate and invoking the delegate.


Approach 2:

class Program
    {

        static void Main(string[] args)
        {
            Action<string> myActionDel = WriteToConsole;
            myActionDel("delegate works");
            Console.Read();
        }

        public static void WriteToConsole(string s)
        {
            Console.WriteLine(s);
        }
    }

you can see here that I did not need to define a delegate explicitly since I knew that my Action delegate is a delegate which fulfills my purpose, it takes a single input parameter and does not return anything.

Examples from .NET framework:
1. Foreach in list type takes Action delegate as input. If you look the metadata of Foreach in list type, it will look like as following

public void ForEach(Action action);

The following code will print "Abhishek" three times (on each invocation of delegate). You can also check below in how many different ways I can use the delegate.

                                  List<string> names = new List<string>();
            names.Add("Abhishek");

            //anonymous delegate way
            names.ForEach(delegate(string s) { Console.WriteLine(s); });

            //lambda expression way
            names.ForEach(s => Console.WriteLine(s));

            //proper delegate way
            Action<string> del = (string s) => { Console.WriteLine(s); };
            names.ForEach(del);



Func Delegate: Now let’s discuss about Func delegate. This is the most used inbuilt delegate since it can take any number of parameters (though there is a cap but that is too high for our general purposes) and it can return a type. Looking at metadata for Func delegate which can encompass a function taking two input parameters and a return type looks something like below

    public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

Kindly note that when you define a Func delegate, the last parameter is always a return type.

Example:

class Program

    {

        static void Main(string[] args)

        {

            Func<stringstring> myFuncDel = WriteToConsole;

            Console.WriteLine(myFuncDel("This is an example of Func delegate"));

            Console.Read();

        }



        public static string WriteToConsole(string s)

        {

            return s;

        }

    }

Note that Func tells that this can encapsulate a function which takes a string input parameter and returns a string output.


Predicate: Predicate is a delegate which takes any object type as input and returns a Boolean. A predicate is equivalent to

 public delegate bool Predicate<in T>(T obj);

or

public Func<objectbool> myPredicate;

Predicates are designed to be used in places where you want to evaluate something and return a Boolean value based on whether your test passed or failed.

 class Program

    {

        static void Main(string[] args)

        {

            Predicate<string> MyPredicate = CheckMyName;

            Console.WriteLine("Is my name Abhishek: " + MyPredicate("Abhishek"));

            Console.Read();

        }



        public static bool CheckMyName(string s)

        {

            return s == "Abhishek";

        }

    }

In .NET framework, you will find predicates used in for e.g. List.Find, Array.Find etc.

public T Find(Predicate match);



3 comments:

  1. Thanks Muhammad, kindly keep on posting your comments and suggestions about blog articles.

    ReplyDelete
  2. Grey Font on Grey Background :S

    ReplyDelete
  3. Thanks for your feedback. Actually that is something I don't like in blogspot, it does not provide too many features to put your code or keep consistency in fonts or styles in your article. I just wrote code in the Visual Studio and pasted it and rest of the evil is done by its designer tool.
    I shall try to attach the code itself or shall change the font color for better readability.
    Thanks once again.

    ReplyDelete