2016-11-27 71 views
1
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表达式如何知道第二个参数是数组中字符串的索引。Lambda Expressing麻烦理解MSDN示例

+1

你所说的'know'意思?第二个参数包含索引,因为这是通过'Where'传递给它的东西,就像第一个参数是源序列中的元素一样。 – Lee

+0

因为它在文档中https://msdn.microsoft.com/zh-cn/library/bb549418(v=vs.110).aspx –

回答

1

lambda表达式总是由出两个部分组成:

  • 在拉姆达操作者=>的前面是输入参数(一个或多个)。在你的情况下,.Where操作给出一个字符串和一个称为(digit, index)的整数。
  • 之后lambda运算符是返回一个布尔(通过使用这两个参数)的代码。你也可以把它写这样的:

一切的一切,你可以了解expresison这样的功能:

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

手段,功能与比他们arrayindex下长度所有数字返回true。

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); 

这里唯一的区别是,我转换的拉姆达为实际的方法:

static bool PredicateMethod(string digit, int index) 
{ 
    return digit.Length < index; 
} 
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; 
} 
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