Lambda Expression Tutorial
Understanding Lambda Expression can be hard, but it doesn't have to
This Lambda Expression tutorial will try to make you get it in the easy way.
The tutorial content:
1) Overview
2) Simple Example
3) Simple Syntax
4) Syntax Rules
5) Advance examples
6) Case study
Lambda Expression Overview
1) WHY do we need Lambda Expression? (What the motivation behind it?)Lambda expression is a Syntax Sugar , it's allows you type less code
2) WHAT is Lambda Expression?
Lambda expression is a Anonymous Function and it is mostly used to create delegates using LINQ
It can also used to create expression tress
3) HOW we define Lambda expression?
Lambda basic definition is Parameters => Executed code
Simple Example
Delegate int Mult(int x, int y); //declaration of delegate type
Mult mult = (x,y) => x * y; //defining delegate object
// and bound the lambda to it
int res = mult(2,3); // after this line res is equal to 6
Simple Syntax
For sake of simplicity Func keyword is going to be used instead of declaring delegates
Func<int> foo = () => 1 //Lambda takes 0 parameters and returns the number 1
Func<int,int> foo = x => x + 1 //Lambda with 1 input parameter
Func<int,int,int> foo = (x,y) => x * y //Lambda with 2 input parameter
Func<int,int,int,int> foo = (x,y,z) => {x += y; return x*z; }
Syntax Rules
1) The parentheses are optional only if the lambda has one input parameter2) You need to put {} over the body if there are two or more statements
3) If the compiler can't understand the input type, in order to allow autocompletion you need to specify types
(int x, string s) => s.Length > x
4) Lambda Expression Closure : the executed code can use parameters which lives
Inside the same scope the lambda is defined.
Example of Lambda Closure:
int i = 3;
Func<int,bool> myFunc = (x) => x > i; //Note that i variable can be accessed
bool res = myFunc(4) //res will be equal to true, because 4 is larger than 3
Advanace Examples
1) Lambda expression is widely used with LINQ
List<int> grades = new List<int>{76,97,82};
List<int> goodGrades = grades.where(g => g > 80).ToList();
//goodGrades contains the numbers 82 and 97
Lets try to understand what happened here? g => g > 80 //This Lambda defines a predicate which returns true if g is grater than 80
The Where method iterate over each item in grades list and if item is above 80 it will get into goodGrades list
public static class Enumerable
{
public static IEnumerable Where( //Where method is part of LINQ
this IEnumerable source, //LINQ is extending IEnumerable
Predicate predicate) //Predicate is special case of Func, it returns bool
{
IEnumerable res = new List<T>();
foreach (T item in source)
{
if (predicate(item)) // Here if item is above 80 it will add to the result
{
res.Add(item);
}
}
return res;
}
//...
}
Ok, so now after you gain enough intuition what happens, Lets see the real implementation of Where method
1) It first checks for errors, then calls to the implementaion method (Single Responsibility Principle)
2) WhereImpel method use the yeild return keyword
public static class Enumerable
{
public static IEnumerable Where(
this IEnumerable source,
Predicate predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
return WhereImpel(source, predicate); //If input is ok, let goes for the real stuff
}
private static IEnumerable WhereImpel(
IEnumerable source,
Predicate predicate)
{
foreach (T item in source)
{
if (predicate(item)) // Here if item is above 80 we return it..
{
yield return item; //see explanation of yeild return keyword above
}
}
}
/...
}
2) Using Lambda to simplify
Events Handlers
//a) Before Lambda Expression declaring event handler looked like:
DropDownList.SelectedIndexChanged += new EventHandler(DropDownList_SelectedIndexChanged);
protected void DropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());};
}
//b) With Lambda it become a single line
DropDownList.SelectedIndexChanged += (sender, e) => {this.Click += (s, e) => { MessageBox.Show(((MouseEventArgs)e).Location.ToString()); };
The Task: Get the excellent students
In this section we will see how using Lambda and LINQ can reduce the key strokes
1. Simple foreach loop: 139 key strokes
var bestStudents = new List<Student>();
foreach (var student in students)
{
if (student.average > 90)
bestStudents.Add(student);
}
2. Using Array.FindAll static method: 137 key strokes, not such a big improvement
var bestStudents = Array.FindAll(students, IsBestStudent);
static bool IsBestStudent(Student student)
{
return student.average > 90;
}
3. Using Anonymous Delegate:
107 key strokes, a little better
var bestStudents = Array.FindAll(students,
delegate(Student student)
{
return student.average > 90;
});
4. Using Lambda Expression: 102 key strokes, again a little better Note that we just replaced the word delegate with the => sign
var bestStudents = Array.FindAll(students,
(Student student) => { return student.average > 90; });
5. Leverage the power of Lambda expression: 67 key strokes, much better!
var bestStudents = Array.FindAll(students,
s => s.average > 90);
6. Using LINQ: 55 key strokes, again another nice improvement :)
var bestStudents = students.Where(s => s.average > 90);
To summary it up we reduced the key strokes from 139 to 55, it's less than 40%, writing less == reading less
Thats all for the Lambda Expression Tutorial,
I hope you learn much more than you expected,
Please leave a comment if you find it usefull, you have a question or you have a comment..