In the previous post, we saw that the Lambda expressions can be used as a shortcut to function pointers. A method that accepts a lambda expression as a parameter is equivalent to a method that accepts a function as a parameter. Let’s understand this with an example.
We’ll create a delegate that checks if the given number is an even number or not. We’ll instantiate this delegate and use it.
class LambdaTest{ delegate bool IsEven(int num); static void Main(string[] args) { IsEven isEvenObj = num => num % 2 == 0; Console.WriteLine(isEvenObj(131)); } }
We’ve defined an IsEven delegate and instantiated it and used it. IsEven is just compiled to a class that inherits System.MultiCastDelegate. Instead of defining a delegate that accepts an integer and returns a boolean, we can use a simple built-in delegate called Func for this purpose. Let’s rewrite the code using Func<>
class LambdaTest{ static void Main(string[] args) { Func<int, bool> isEven = num => num % 2 == 0; Console.WriteLine(isEven(131)); } }
Func<> is a built-in delegate class in C#. It accepts nearly 16 generic parameters, the last parameter being the return value. In our example Func<int,bool> indicates it accepts an integer and returns a boolean. Similar to Func<> is the Action<> delegate as well. It just doesn’t return any value. The ForEach methods in collection classes accept the Action<> delegate as parameter.
class LambdaTest{ static void Main(string[] args) { List<string> langs = new List<string>() { "C#", "Java","Ruby","Groovy" }; Action<string> action = s => Console.WriteLine(s); langs.ForEach(action); } }
Therefore we just need to understand that the lambda expressions are nothing but objects of delegate classes, with a crisp syntax.