Friday, July 08, 2016

Understand Action, Func and Delegate, workflow, calls with Lambda & Anonymous method etc.

Action is a delegate (pointer) to a method, that takes zero, one or more input parameters, but does NOT return anything.

Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and DOES returns a value (or reference).
Predicate is a special kind of Func often used for comparisons.

The difference between Func and Action is simply whether you want the delegate to return a value (use Func) or not (use Action).

Action does not return value. Func and Action take up to 16 parameters, Func take one extra parameter for Return, so total parameter for Func is 17.

C#.NET Example to use Func & Action 

public static double CalculateSomething(int i, int j)
{
   return  new double();
}

public static void DoSomething(int i, int j)
{
    Console.WriteLine("we are here...");
}

//Call
Func<intintdouble> myFunc = (CalculateSomething);

Action<intint> myAction = (DoSomething);

double is return.output parameter

How Delegate works, just to compare with Action & Func

Delegate is a type which holds the method(s) reference in an object. It is also referred to as a type safe function pointer.

//Delegate declare
public delegate int MyOwnDelegate(int i, int j);

private int ShowAddition(int i, int j) { return i + j; }

private int ShowMultipy(int i, int j) { return i * j; }

//Call
MyOwnDelegate dele = new MyOwnDelegate(ShowAddition);
dele(10, 20); //Output 30

//If it hold reference of more then one method then it called MultiCast Delegate
dele += new MyOwnDelegate(ShowMultipy);
dele(10, 20);  //Output  30 and 200
  
Then the Delegate is added using the += operator and removed using the -= operator.  
                 

How Func works

public sealed class emp
{
   public double Calculate(Func<doubledouble> op)
   {
        return op(20);
   }
}

public class Program
   public static double Display(double i)
   {
       return i*9;
   }
   private static void Main(string[] args)
   {
            //Call
     emp e = new emp();
     double d1 = e.Calculate(Display);

    //Another way to call this function, with inline function
     double d1 = e.Calculate(r => 2*Math.PT*r);
    }
}
  1. ‘Calculate’ function takes input parameter as function name ‘Display’ to execute
  2. First control goes inside ‘Calculate’ function and convert op(20) into Display(20).
  3. Then control go to ‘Display’ function, which is taking ‘20’ as an input parameter and convert i*9 into 20*9 and
  4. Final Output of d1 is 180;

Action uses for Lambda & Anonymous method

public class Base
{
  public void Foo(Action action)
  {
     Console.WriteLine("Action with No Param...");
  }

  public void Foo(Action<int> action)
  {
     Console.WriteLine("Action with ONE param...");
  }
  
  public void Foo(Action<int, int> action)
  {
     Console.WriteLine("Action with TWO param...");
  }
}

//Call
Base d = new Base();
int x = 0;

//lambda expression
d.Foo(() => { x = 0; });       // Call Foo with No param in Action
d.Foo((i) => { x = 0; });      // Call Foo with ONE  param in Action
d.Foo((i, j) => { x = 0; });  // Call Foo with TWO param in Action

//Anonymous Method
d.Foo(delegate() { x = 0; });               // Call Foo with No param in Action
d.Foo(delegate(int i) { x = 1; });          // Call Foo with ONE  param in Action
d.Foo(delegate(int i, int j) { x = 2; });   // Call Foo with TWO param in Action

Func uses for Lambda & Anonymous method

public class Base
{ 
 public int Foo(Func<int> action)
 {
    Console.WriteLine("Func with No Param...");
    return 1;
  }

  public int Foo(Func<int,int> action)
  {
    Console.WriteLine("Func with No Param...");
    return 2;
  }

  public int Foo(Func<int, int,int> action)
  {
    Console.WriteLine("Func with TWO param...");
    return 3;
  }
}

//Call
Base d = new Base();
int x = 0;

//lambda expression
d.Foo(() => 0);                  // Call Foo with No param in Func
d.Foo((int i) => 10);            // Call Foo wit ONE  param in Func
d.Foo((int i, int j) => 20);     // Call Foo with TWO param in Func

//Anonymous Method
d.Foo(delegate() { return 1; });          // Call Foo with No param in Func
d.Foo(delegate(int i) { return 1; });     // Call Foo with ONE param in Func
d.Foo(delegate(int i, int j) { return 1; }); // Call Foo with TWO param in Func