How delegate turned into LINQ
How delegate turned into LINQ

In this blog post we will discuss about the core idea that made one of the coolest features of c# called “LINQ” into a reality. LINQ stands for Language Integrated Query and in simple words, it allows us to write queries against any data collection or data source using c# syntax. Because of LINQ the days of writing “select * from customer” are long gone. So, how LINQ is made? 

To answer that question, we need to have fair knowledge about “delegate” and “extension method”. I have one complete series on “delegate” and I recommend to go through those posts if you are new with the concept.

You might also need to look at the post I have on “extension method” to get familiar with the concept if you already don’t know about it.
Now that you have fair idea about delegate and extension method, it is time to combine them to build LINQ. 

Scenario

We want to fetch all the numbers greater than 5.

Solution

Using our knowledge on extension method we can just write the following method and everything is fine:

static class MyClass
{
public static IEnumerable<int> WhereNumberIsGreaterThanFive(this IEnumerable<int> numbers)
  {
   foreach (var number in numbers)
   {
     if (number > 5)
     {
       yield return number;
     }
   }
  }
}

Now the problem is, if we want to fetch all the numbers less than 5 we need to write another almost similar method.

As you have already figured it out, we are talking about writing method each time. Why don’t we let the user define the method for us and we will just invoke that method. Yeah, delegate allows us to get exactly the same effect.

So, now in our “WhereNumberIsGreaterThanFive” method we will accept another argument of type “Func”. Func is just a fancy type of delegate which always returns some value.

public static IEnumerable<int> WhereNumberIsGreaterThanFive(this IEnumerable<int> numbers,Func<int, bool=""> func)
        {
            foreach (var number in numbers)
            {
                if (func(number)) //invoking the delegate (method)
                {
                    yield return number;
                }
            }
        }

Here, we are just iterating through all of our numbers and invoking the incoming method on each and every numbers. If the result of invoked method is true we are populating the return value by using “yield return”.

Now, our method is completely dynamic meaning we are no more confined to get all the numbers greater than 5 rather we can now do any kind of operation on a collection of int as long as that operation includes taking one integer and returning a boolean. So, we can rename our function like this,

public static IEnumerable<int> Where (this IEnumerable<int> numbers, Func<int, bool=""> func)
        {
            foreach (var number in numbers)
            {
                if (func(number)) //invoking the delegate (method)
                {
                    yield return number;
                }
            }
        }

And we can use this extension method in following various ways,

var greatherThanFive = numbers.Where(n => n > 5 );
var greatherThanTen = numbers.Where(n => n > 10 );
var lessThanFive = numbers.Where(n => n < 5 );
var lessThanTen = numbers.Where(n => n < 10 );

Here, we are passing a method body in its minimalistic form. We don’t need to mention a name for the method because it is an anonymous method. We don’t need to mention the keyword “delegate” because we know that our second parameter for “Where” method should be a Func type. According to the declaration of ( Func) func in the “Where” method, “n” before the “=>” sign is the input of the func. And everything after the “=>” denotes the method body. As we can only have one input parameter, we don’t need to put it within “()” parenthesis. We also don’t have to put the method body within “{}” curly braces as the body has only one line to process. Notice, if we have more than one statement to process then we must put the whole method body within “{}” curly braces and must use “return”. 

March 23, 2015
Jahan Sarwar