如何在LINQ Where()中使用额外的int参数
本文关键字:参数 int LINQ Where | 更新日期: 2023-09-27 18:29:39
请注意,这不是一个关于委托一般是什么的问题。此外,我看过医生,却没有任何智慧。
在LINQ中,我可以使用这样的东西。
using(Model model = new Model())
{
return model.Things
.Where(thing => thing.IsGood);
}
我可以看到返回类型(运算符的左对象)是类型Thing
,条件(运算符的右对象)是bool
。Intellisense告诉我可以从这两个中挑选,我被第二个弄糊涂了。
Func<Thing, bool>
Func<Thing, int, bool>
我假设lambda运算符只是实际调用的语法糖。这是正确的吗?如果是,那个整数在做什么?我该如何指定它?
来自此重载的文档:
谓词
类型:
System.Func<TSource, Int32, Boolean>
用于测试每个源元素的条件的函数;函数的第二个参数表示源元素的索引。
正如这所表明的,整数是元素的索引。
所以,
var everyTwo = input.Where((c, i) => i % 2 == 0);
例如,仅每隔一秒返回一个元素。上面链接的文档有一个稍微复杂一点的用例示例,它涉及两个参数。
我不确定这是否只是一个拼写错误,但您链接到的文档似乎是针对不包含此参数的重载的,这可能解释了为什么您找不到对此的解释。
正如评论中已经提到的,文档指出第二个重载:-
基于谓词筛选值序列。每个元素的索引用于谓词函数的逻辑。
这是参考代码,我想它会让你明白:-
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
Func<TSource, int, bool> predicate)
{
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
return WhereIterator<TSource>(source, predicate);
}
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)) yield return element;
}
}
您可以看到我们提供的索引是如何在foreach
语句中使用的。因此,我们可以将谓词用作:-
.Where((thing, index) => thing.SomeIntProperty <= index * 2);
用一个例子来说明,而不是简单地引用MSDN帮助页面:
取此代码:
var list = new List<string> { "a", "b", "c" }
var index = 0;
foreach (var item in list)
{
if (item == "b" && index == 1) {
Console.WriteLine(item);
}
index++;
}
成为
var list = new List<string> { "a", "b", "c" }
var items = list.Where((item, index) => item == "b" && index == 1)
foreach (var item in items) {
Console.WriteLine(item);
}
(您可以对写行等使用其他linq命令,这是为了说明Where
)
正如MSDN中所说:
基于谓词筛选值序列。每个元素的索引用于谓词函数的逻辑。
你什么时候需要这个?例如,您可能需要所有具有偶数索引的元素:
return model.Things
.Where((thing, index) => index % 2 == 0);
此外,在未来,您可以使用这个为我们提供.net
源代码的网站来更多地发现和学习这些东西。例如,这里是Where()
方法的重叠的实现:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
return WhereIterator<TSource>(source, predicate);
}
我们可以看到它返回WhereIterator
方法:
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)) yield return element;
}
}
我们可以看到,实际上Linq使用了foreach
循环,并通过将index
变量增加一来获得当前元素的索引。
Where上有两篇MSDN文章。你链接到的那个和这个。
用法语法如下。
using(Model model = new Model())
{
return model.Things
.Where((thing, counter) => thing.IsGood < counter);
}
正如您所看到的,它在这个特殊情况下没有什么意义,我从来没有需要使用它。然而,如果需要,它就在那里。您可以在提供的链接中找到一个示例。