Func<> Delegates in LINQ

Introduction
 
A delegate is a C# type similar to function pointers in C++. It encapsulates references to one or multiple methods. Func<> is a special kind of Multicast Delegate used frequently with LINQ and Enumerable extensions. Let's have a close look at Func<> delegates.
 
Func Delegates
 
Func delegates are pointers to methods that take one or more parameters and must return a value. There are many overloaded Func delegates. Please see the documentation for a better understanding of those. In this article let's have a general idea of how to use it programmatically.
 
Usage
 
Generelly it's used with anonymous methods as follows: 
  1. Func<intintintlong> add = delegate(int a, int b, int c) { return a + b + c; };  
  2.  Console.WriteLine(add(2, 3, 4)); // Outputs "9"  
The similar kind can be replaced by a lambda expression that is more readable and easy to write and understand. 
  1. Func<intintintlong> add = (a, b, c) => a + b + c;  
  2.  Console.WriteLine(add(2, 3, 4)); // Outputs "9"   
But the difference is that the return type is inferred by the compiler this time.
 
You don't use the Func<> as in the preceding examples generally. The most usefulness of Func<> is when you want to build an extension method and use it globally. Most of the LINQ extensions take Func as a parameter. Here is a simple use:  
  1. public static bool EnumerableContains<S, T>(this IEnumerable<S> obj,  
  2. Func<S, T> comparer, T valueToMatch)  
  3. {  
  4.     return obj.Any(l => comparer(l).Equals(valueToMatch));  
  5. }  
You can call this on an IEnumerable object as: 
  1. var obj = new List<Person> { new Person { ID = 1, Name = "Arunava" }, new Person { ID = 2, Name = "Bubu" } };  
  2. bool res=obj.EnumerableContains(data => data.Name, "Bubu");  
  3. Console.WriteLine(res); // Outputs "True"  
Func delegates also support co-variance and contra-variance. It means you can pass a parent class and can return a subclass object and vice-versa.
 
The casting happens internally by the compiler, so you don't need to worry about it. Let's see a simple example: 
  1. static string PrintHellow() { return "Hellow!"; }  
  2. static void Main()  
  3. {  
  4.     Func<object> delegateObj = PrintHellow;  
  5. }  
Here, the method's return type is a string that is lower in the class hierarchy than an object. But this code is supported in C# 5.0 and produces the expected result. You don't need to typecast it internally. This is a great support provided by C# delegate.
 
The Func as Predicate
 
Previously we have an object in C# called a Predicate. It is still supported but generally the modern C# programmers understand Predicate as a special kind of Func delegate. This kind of func delegate returns a bool. This is mostly used in expressions and LINQ. Let's see the example of a StartsWith extension. It expects a predicate as a parameter as in the following:
  1. var obj = new List<Person> { new Person { ID = 1, Name = "Arunava" }, new Person { ID = 2, Name = "Bubu" } };  
  2. var result = obj.Where(data => data.Name.StartsWith("b",StringComparison.CurrentCultureIgnoreCase));  
I hope this helps.


Similar Articles