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表达式如何知道第二个参数是数组中字符串的索引。
答案 0 :(得分:1)
Lambda表达式总是由两部分组成:
=>
前面是输入参数。在您的情况下,.Where
操作会给出一个字符串和一个名为(digit, index)
的整数。总而言之,你可以像这个函数一样理解表达式:
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 source,Where
调用WhereIterator
方法,其中包含所有索引逻辑:
int index = -1;
foreach (TSource element in source) {
checked { index++; }
if (predicate(element, index)) yield return element;
}