Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do "Where" and "Select" work in LINQ?

Tags:

c#

linq

I have the following snippet of code. I have few queries regarding the code snippet which I have mentioned after it.

var salaries = customerList
                    .Where(c => c.Age > 30)
                    .Select(c => c.Salary) // salary is of type long
                    .ToList();
  • In above snippet of code, how does "Where" get access to the customerList and how does it define the type of "c"?
  • Does "Where" return a temporary list of customers after applying the filter on which the Select acts?
  • How exactly does "Select" know that it has to return only the "Salary"?
  • How does the type of the variable "salaries" get set to List< long >?
like image 744
Sharath Avatar asked Oct 19 '25 03:10

Sharath


2 Answers

Where is probably implemented like this (note that this is a very rough implementation, just do give you an idea of what it is like):

public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
    foreach (T t in source) {
        if (predicate(t)) {
            yield return t;
        }
    }
}

Note that Where is an extension method. You are essentially calling Where(customerList, c => c.Age > 30). Now you should see where it gets access of the customerList. It also infers what T should be by looking at what kind of IEnumerable customerList is. Since it is a IEnumerable<Customer>, T is Customer, and so it expects a Func<Customer, bool> for the second argument. This is how it knows that c is Customer.

Where does not return a temporary list. A lot of LINQ methods make use of deferred evaluation. Where returns an IEnumerable<Customer> that is filtered. Remember that IEnumerable is just a sequence of things. This sequence returned by Where however, is not evaluated, until you ask for it. Select does the same as well. So a list is not created until you call ToList.

Your third question is kind of like asking "How does Where know how to filter" or "How does Console.WriteLine know how to write to the screen". That's what Select does. You can look at its implementation if you want. Here's a rough sketch:

public static IEnumerable<U> Select<T, U>(this IEnumerable<T> source, Func<T, U> mapping) {
    foreach (T t in source) {
        yield mapping(t);
    }
}

The type of the variable salaries is determined by looking at the method signatures of each of the methods you call. Your Select call returns a IEnumerable<long>, and ToList's signature tells the compiler that, given a IEnumerable<T> it will return List<T>, so in this case, it returns a List<long>.

like image 79
Sweeper Avatar answered Oct 21 '25 15:10

Sweeper


Where clause exists in Enumerable class which uses for querying in .net framework. it provides as boolean condition and return source. It will convert to respective sql query eventually.

so your linq

var salaries = customerList
                    .Where(c => c.Age > 30)
                    .Select(c => c.Salary) // salary is of type long
                    .ToList();

old school sql command

SELECT [c].[Salary] FROM [CustomerList] WHERE [c].[Age] > '30'
like image 41
phonemyatt Avatar answered Oct 21 '25 16:10

phonemyatt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!