【发布时间】:2009-12-21 04:35:30
【问题描述】:
谁能解释一下 LINQ 函数 Where(..) 和 FindAll(..) 有何不同?他们似乎都在做同样的事情......
【问题讨论】:
谁能解释一下 LINQ 函数 Where(..) 和 FindAll(..) 有何不同?他们似乎都在做同样的事情......
【问题讨论】:
FindAll() 是List<T> 类型的函数,它不是像Where 这样的LINQ 扩展方法。 LINQ 扩展方法适用于实现IEnumerable 的任何类型,而FindAll 只能用于List<T> 实例(当然,或者从它继承的类的实例)。
此外,它们的实际用途不同。 Where 返回IEnumerable 的实例,在枚举对象时按需执行。 FindAll 返回一个新的 List<T>,其中包含请求的元素。 FindAll 更像是在 IEnumerable 的实例上调用 Where(...).ToList()。
【讨论】:
对我来说最大的不同是 .FindAll 在 .Net 2.0 中也可用。我并不总是有幸在 .Net 3.5 中编程,所以我尽量记住 .Net 泛型集合的“本机”方法。
有好几次我自己实现了一个已经可用的 List 方法,因为我无法对其进行 LINQ。
在这种情况下我觉得很方便的是,使用 VS2008,我可以使用类型推断和 lambda 语法。这些是编译器功能,而不是框架功能。这意味着我可以写这个并且仍然保留在 .Net 2.0 中:
var myOddNums = myNums.FindAll(n => n%2==1);
但是,如果您确实有可用的 LINQ,那么保持延迟执行和立即执行之间的区别很重要。
【讨论】:
如果我没记错的话,主要区别(除了它们的实现方式:IEnumerable<T> 与 List<T>)是Where 实现了延迟执行,在您需要之前它实际上不会进行查找它——例如在 foreach 循环中使用它。 FindAll 是立即执行方法。
【讨论】:
我对 80K 个对象的列表进行了一些测试,发现 Find() 可以比使用 Where 和 FirstOrDefault() 快 1000%。直到在每次通话之前和之后测试一个计时器,我才知道这一点。有时它是同一时间,有时它更快。
【讨论】:
性能方面FindAll() 更好,下面是一个示例。 FindAll 需要 3 毫秒,而 Where 需要 11 毫秒。
public class SortedSearch
{
public static int[] CountNumbersUsingFindAll(int[] sortedArray, int lessThan)
{
var smaller = Array.FindAll(sortedArray,x => x < lessThan);
return smaller;
}
public static IEnumerable<int> CountNumbersUsingWhere(int[] sortedArray,int lessThan)
{
var smaller = sortedArray.Where(x => x < lessThan);
return smaller;
}
}
class Program
{
static void Main(string[] args)
{
Stopwatch s = Stopwatch.StartNew();
Console.WriteLine(SortedSearch.CountNumbersUsingFindAll(new int[]{1,3,5,7},4));
Console.WriteLine(s.ElapsedMilliseconds);
s.Stop();
s.Restart();
Console.WriteLine(SortedSearch.CountNumbersUsingWhere(new int[] { 1, 3, 5, 7 }, 4));
Console.WriteLine(s.ElapsedMilliseconds);
s.Stop();
Console.ReadKey();
}
}
【讨论】: