Linq:Select和Where有什么区别

时间:2009-07-31 14:10:16

标签: .net linq select where

Linq中提供了SelectWhere方法。每个开发人员应该了解这两种方法?例如:何时使用一个而不是另一个,使用一个优于另一个,等等。

7 个答案:

答案 0 :(得分:100)

<强>其中

找到匹配的项目,只返回那些(过滤)。

- &GT; IEnumerable<A> in,IEnumerable<A> out

选择

返回源中所有项目的内容(投影/转化)。那些东西可能是物品本身,但通常更像某种投射。

- &GT; IEnumerable<A> in,IEnumerable<B> out

答案 1 :(得分:43)

选择其中是两个完全不同的操作符,作用于 IEnumerable

第一个是我们称之为投影操作员,而最后一个是限制操作员

了解此类运营商行为的一种有趣方式是查看其“功能类型”。

  • 选择:(IEnumerable&lt; T1&gt;,Func&lt; T1,T2&gt;)→IEnumerable&lt; T2&gt; ;它将包含T1类型元素的IEnumerable和将类型T1转换为T1类型元素的函数作为输入。输出是包含T2类型元素的IEnumerable。

    由此可以很容易地猜到这个运算符将通过在输入IEnumerable的每个元素上应用输入函数并将结果包装在新的IEnumerable中来产生其输出。

    使用类似数学的表示法,它将输入(a,b,c,...):IEnumerable&lt; T1&gt; f:T1→T2 并产生(f(a),f(b),f(c),......):IEnumerable&lt; T2&gt;

  • 其中:(IEnumerable&lt; T1&gt;,Func&lt; T1,bool&gt;)→IEnumerable&lt; T1&gt; ;这一个采用包含T1类型的元素的IEnumerable和T1上的谓词(即,为T1类型的输入生成布尔结果的函数)。您会看到输出也是包含T1类型元素的IEnumerable。

    这次可以猜测输入IEnumerable的元素将出现在输出IEnumerable上,具体取决于谓词应用于元素的结果。除此之外,运算符名称的语义还可以确保它将通过从输入中仅获取谓词应用程序中计算结果为true的元素来生成输出IEnumerable。

具有功能编程背景的人通常会这样想。它允许你只通过查看它的类型来推断(或至少猜测......)运算符的作用!

作为练习,在查看文档之前,尝试查看LINQ在IEnumerables上介绍的其他运算符并推断它们的行为!

答案 2 :(得分:40)

他们是截然不同的:

Select完全是关于转化

Where完全是关于过滤的。

答案 3 :(得分:17)

选择将可枚举的地图映射到新结构。如果在IEnumerable上执行select,您将获得一个具有相同数量元素的数组,但是根据您指定的映射具有不同的类型。在哪里过滤IEnumerable,以便它为您提供原始IEnumerable的子集。

答案 4 :(得分:7)

如果您知道他们如何实现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;
        }
    }
}

选择implementation ::

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实现的扩展方法不同,因为它们使用表达式树来实现相同的。

答案 5 :(得分:4)

Where〜=过滤器

Select〜=地图

两个都返回IEnumerable<T>

答案 6 :(得分:1)

如果选择“选择”,则可以映射到新结构的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> ]