This is a very short and quick article to demonstrate various uses of lambda expressions in C#. I believe lambda expressions is one of the nicest features introduced in C# 3.0.
So let's start with a little theory and then we will get to a practical session.
What lambda expressions are
A lambda expression is an anonymous function and it is usually used to create delegates in LINQ. Simply put, it's a method without a declaration; in other words, an access modifier, a return value declaration and a name.
Fine, so a lambda expression is nothing but an anonymous function that doesn't have a name, just an input and output, that's all.
If it is not reusable, why use it?
Generally, the question may arise, if the function doesn't have a name, then it's not reusable anywhere. Which is not a good idea in terms of good development practices. Yes I agree but there are specific situations where lambda expressions can perform a smart role. We will figure out the situation where lambda expressions can perform better.
How it works
To create a lambda expression, you specify input parameters (if any) on the left side of the lambda operator => and you put the expression or statement block on the other side. For example, the lambda expression x => x * x specifies a parameter that's named x and returns the value of x squared and the number of inputs may be any number.
Show me one example
Yes, I too want an example. Here is a simple example of a lambda expression. You may think, why do I have (and many) an attached lambda expression with delegates? The reason is simple, as we know a lambda expression is nothing but an anonymous function and delegates know how to handle a function, since it is nothing but a function pointer. So, generally when we want to implement an anonymous function, we need to ensure someone is pointing to the function.
- class Program
- {
- delegate Boolean mydel(int data1,int data2);
- static void Main(string[] args)
- {
- mydel d = (x,y) => x>y;
- Console.WriteLine(d(10, 20));
- Console.ReadLine();
- }
- }
Otherwise we cannot invoke the function in the future. So, let's understand the example. As we said, a lambda expression has only an input and output as in the following:
- mydel d = (x,y) => x>y;
- Console.WriteLine(d(10, 20));
X and Y are the input and output boolean values, the expression pattern is such that we have attached it with the same type of delegate.
Here is sample output.
Expression lambda
If the right side of a lambda expression carries an expression tree then this kind of lambda expression is called an expression lambda. Yes, the example that we have see just now is one example of an expression lambda. Here is another one.
- class Program
- {
- delegate int mydel(int data1,int data2, int data3);
- static void Main(string[] args)
- {
- mydel d = (x, y ,z) => (x > y == true) ? (x > z == true) ? x : z : (y> z == true)? y:z;
- Console.WriteLine(d(50,60,30));
- Console.ReadLine();
- }
- }
Yes, we should not write this kind of logic in a real application, it may cause frustration for someone else. In this example we have implemented the three number comparison algorithyms in a single line lambda expression. So, have a look at the right side and you will find a big expression.
Statement lambda
A statement lambda will contain a statement in the right hand side of the lambda expression. Have a look at the following example.
- class Program
- {
- delegate void mydel();
- static void Main(string[] args)
- {
- mydel d = () => Console.WriteLine("Statement lambda");
- d.Invoke();
- Console.ReadLine();
- }
- }
Here we have invoked the Console.WriteLine() function by a delegate using a lambda expression. Here is the output.
It's not that a statement lambda can execute one and only one statement. We can execute multiple statements too. Have a look at the following example.
- public class test
- {
- public static void hello()
- {
- Console.WriteLine("I am hello function");
- }
- }
- class Program
- {
- delegate void mydel();
- static void Main(string[] args)
- {
- mydel d = () => {
- Console.WriteLine("I am first statement");
- test.hello();
- };
- d.Invoke();
- Console.ReadLine();
- }
- }
Here the pattern of both Console.WriteLine() and fun() are the same so that we have attached both in the same delegate and invoked it. Here is sample output.
Lambda expression with Func
A Lambda expression fits sweetly with a Func. We know that a Func is an anonymous delegate and we can attach an anonymous function to it. Since a lambda expression is nothing but a function, we can attach it with the Func . In the following example we will attach a lambda expression with fun anonymous delegates.
- class Program
- {
- static void Main(string[] args)
- {
- Func<int, int, Boolean> fun = (x, y) => x > y;
- Console.WriteLine(fun(10, 10));
- Console.ReadLine();
- }
- }
Here is sample output.
Lambda expression fit nice with collection
Yes, the real use of a lambda expression is with a collection. It's very handy to sort and/or shuffle a collection using a lambda expression. Here are a few examples.
- class person
- {
- public string name { get; set; }
- }
- class Program
- {
- static void Main(string[] args)
- {
- int[] data = { 1, 2, 4, 5, 6, 10 };
-
- int[] even = data.Where(fn => fn % 2 == 0).ToArray();
-
-
- int[] odd = data.Where(fn => fn % 2 != 0).ToArray();
-
- List<person> persons = new List<person> {
- new person {name = "Sourav"},
- new person {name = "Sudip"},
- new person {name = "Ram"}
- };
-
-
- List<person> nameWithS = persons.Where(fn => fn.name.StartsWith("S")).ToList();
- Console.ReadLine();
- }
- }
Lambda expression in async
I hope you know the concept of Asynchronous programming in C# 5.0. Asynchronous programming is the updated version of multithreading in C#, anyway let's see how to use a lambda expression to execute a task asynchronously. Have a look at the following example.
- namespace Client
- {
- public class AsyncClass
- {
- public async Task<string> Hello()
- {
- return await Task<string>.Run(()=>{
- return "Return From Hello";
- });
- }
- public async void fun()
- {
- Console.WriteLine(await Hello());
- }
- }
-
- class Program
- {
- static void Main(string[] args)
- {
- new AsyncClass().fun();
- Console.ReadLine();
- }
- }
- }
And here is the output. In this example we are returning a string but if needed we can return any type of data.
Let's use an anonymous function and async together
Here we will modify the previous example a little bit. We will now execute the function using a lambda expression asynchronously. Have a look at the following example.
- namespace Client
- {
- public class AsyncClass
- {
- public string Hello(string name)
- {
- return name;
- }
-
- public async Task<string> Hello()
- {
- return await Task<string>.Run(()=>{
-
- Func<string, string> del = x => x;
- return del.Invoke("sourav");
- });
- }
- public async void fun()
- {
- Console.WriteLine(await Hello());
- }
- }
-
- class Program
- {
- static void Main(string[] args)
- {
- new AsyncClass().fun();
- Console.ReadLine();
- }
- }
- }
Here is the output.
Conclusion
Now, let's understand why to use a lambda expression and in which scenario they fit. We have seen that a lambda expression can replace anonymous functions and make the code size short but it's always recommended to use a lambda expression in a simple way, because it reduces code readability.
So, use a lambda expression when it's necessary to implement something simple and it is not necessary to use it more than once in the application.