Lambda表达难以理解MSDN示例

时间:2016-11-27 14:14:29

标签: c# lambda

string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

var shortDigits = digits.Where((digit, index) => digit.Length < index);  
foreach (var sD in shortDigits)  
{  
    Console.WriteLine(sD);  
}

MSDN给出了上面的代码示例,我理解“digit”表示数组中的一个字符串。我不明白的是Lambda表达式如何知道第二个参数是数组中字符串的索引。

4 个答案:

答案 0 :(得分:1)

Lambda表达式总是由两部分组成:

  • 在lambda运算符=>前面是输入参数。在您的情况下,.Where操作会给出一个字符串和一个名为(digit, index)的整数。
  • 在lambda运算符之后是返回bool的代码(通过使用这两个参数)。你也可以这样写:

总而言之,你可以像这个函数一样理解表达式:

bool WhereDigits(string digit, int index)
{
    return digit.Length < index;
}

意味着,对于长度小于arrayindex的所有数字,函数返回true。

答案 1 :(得分:1)

  

Lambda表达式如何知道第二个参数是数组

中字符串的索引

Lambda表达式不知道。 Where扩展方法知道因为它的实现方式。

Lambda只需要一些参数来完成你的工作。谁发送参数? Where扩展方法,如下所示。

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
    int index = -1;
    foreach (TSource element in source) {
        checked { index++; }

        if (predicate(element, index)) // the element and index is being sent to the function. your function executes here.
             yield return element;
    }
}

然后在此处给出参数以运行代码

(digit, index) => return digit.Length < index

答案 2 :(得分:0)

好吧,因为这个重载是像这样实现的(删除泛型以使其更容易):

static IEnumerable<string> Where(string[] sequence, Func<string, int, bool> predicate)
{
    int index = 0;
    foreach(var item in sequence)
    {
        if (predicate(item, index))
            yield return item;

        index++;
    }
} 

因此,此实现将项的索引发送到lambda表达式。

所以,你这样称呼它:

string[] digits = { "zero", "one", "two", "three", "four", 
                    "five", "six", "seven", "eight", "nine" };

var result = Where(digits, PredicateMethod);

这里唯一的区别是我将lambda转换为实际方法:

static bool PredicateMethod(string digit, int index)
{
    return digit.Length < index;
}

答案 3 :(得分:0)

Where方法有两个重载。其中一个需要Func<string, bool>,另一个需要Func<string, int, bool>。你在这里打电话显然是后者。

Func<string, int, bool>委托表示一个接受两个参数(一个int和一个字符串)并返回bool的方法。您的lambda表达式有两个参数并返回bool。因此代码编译。

现在,Where方法如何知道索引?

这会调用Where方法的内部工作方式。通过查看reference sourceWhere调用WhereIterator方法,其中包含所有索引逻辑:

int index = -1;
foreach (TSource element in source) {
    checked { index++; }
    if (predicate(element, index)) yield return element;
}