Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do multi-parameter linq expression initialize their parameter?

Tags:

c#

lambda

linq

In this post the solution to the problem is:

list.Where((item, index) => index < list.Count - 1 && list[index + 1] == item)

The concept of multi-parameter (ie (item, index)) is a bit puzzling to me and I don't know the correct word to narrow down my google results. So 1) What is that called? And more importantly, 2) How are the non-enumerable variable initialize? In this case how is index compiled as an int and initialized to 0?

Thanks.

like image 490
E.Beach Avatar asked Nov 18 '10 14:11

E.Beach


2 Answers

Lambda expressions have various syntax options:

() => ... // no parameters
x => ... // single parameter named x, compiler infers type
(x) => ... // single parameter named x, compiler infers type
(int x) => ... // single parameter named x, explicit type
(x, y) => ... // two parameters, x and y; compiler infers types
(int x, string y) => ... // two parameters, x and y; explicit types

The subtlety here is that Where has an overload that accepts a Func<T, int, bool>, representing the value and index respectively (and returning the bool for the match). So it is the Where implementation that supplies the index - something like:

static class Example
{
    public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
        Func<T, int, bool> predicate)
    {
        int index = 0;
        foreach (var item in source)
        {
            if (predicate(item, index++)) yield return item;
        }
    }
}
like image 97
Marc Gravell Avatar answered Oct 09 '22 00:10

Marc Gravell


When using LINQ, remember that you are passing a method delegate to the Where method. The particular overload of Where that you are invoking takes a method with signature Func<T,int,bool>, and will call this method for each item in list. Internally, this particular method is keeping count for every item iterated, and calling the supplied delegate using this value as the second parameter:

var result=suppliedDelegate(item,count)
like image 38
spender Avatar answered Oct 09 '22 00:10

spender