Answers:
哪里
查找匹配的项目,仅返回匹配的项目(过滤)。
- > IEnumerable<A>
中,IEnumerable<A>
出
选择
返回源中所有项目的某些内容(投影/转换)。这些东西可能是物品本身,但通常更是某种形式的投影。
- > IEnumerable<A>
中,IEnumerable<B>
出
Select
将始终返回列表中相同数量的元素(无论您可能具有哪种过滤条件)。 Where
可以根据您的过滤条件返回较少的元素。
Where == filter
和Select == map
Select和Where是作用于IEnumerable的两个完全不同的运算符。
第一个是我们称为投影算子,而最后一个是限制算子。
了解此类操作员行为的一种有趣方式是查看其“功能类型”。
选择:(IEnumerable <T1>,Func <T1,T2>)→IEnumerable <T2> ; 它以IEnumerable包含类型T1的元素和将类型T1的元素转换为类型T2的函数作为输入。输出是IEnumerable,其中包含类型T2的元素。
由此,可以通过将输入函数应用于输入IEnumerable的每个元素,并将结果包装在新的IEnumerable中,轻松地猜出该运算符将产生其输出。
使用一些类似于数学的表示法,它以(a,b,c,...)作为输入:IEnumerable <T1>和f:T1→T2并产生(f(a),f(b),f(c) ,...):IEnumerable <T2>
其中:(IEnumerable <T1>,Func <T1,bool>)→IEnumerable <T1> ; 此函数采用一个IEnumerable,其中包含类型T1的元素和一个关于T1的谓词(即,为类型T1的输入生成布尔结果的函数)。您会看到输出也是一个IEnumerable,其中包含类型T1的元素。
这一次,人们可能会猜测谓词输入IEnumerable的元素将出现在输出IEnumerable上,这取决于谓词对该元素的应用结果。通过添加运算符名称的语义,可以确保通过将输入中的那些仅在谓词应用中计算为true的元素从输入中取出,从而确保它会生成输出IEnumerable。
具有函数式编程背景的人们通常会这样认为。它允许您仅通过查看操作符的类型来推断(或至少可以猜测...)!
作为练习,在查看文档之前,请尝试查看LINQ在IEnumerables上引入的其他运算符,并推断其行为!
如果您知道他们是如何实现Where并选择扩展方法的,则可以预测它的作用。
在哪里实现::
public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{
foreach ( var data in a )
{
//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
if ( Method.Invoke ( data ) )
{
yield return data;
}
}
}
选择实施::
public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<TSource> a , Func<TSource , TResult> Method )
{
foreach ( var item in a )
{
//Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
yield return Method.Invoke ( item );
}
}
我的实现对于任何集合都可以正常工作...但是它不同于Microsoft实现的扩展方法,因为它们使用表达式树来实现相同的方法。
如果选择“选择”,则可以映射到新结构的IEnumerable。
A.Select(x=>new X{UID=x.uid, UNAME=x.uname})
//input as [IEnumerable<A>] --------> return output as [IEnumerable<X> ]
where()作为IEnumerable的过滤器,它将根据where子句返回结果。
A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] --------> return output as [IEnumerable<A> ]