有人能解释一下 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 泛型集合的“本地”方法。
已经发生过好几次,因为无法使用LINQ,我自己实现了一个已有的List方法。
在这种情况下,我觉得很方便的是,使用VS2008,我可以使用类型推断和lambda语法。这些是编译器功能,而不是框架功能。这意味着我可以编写以下代码,并仍然保持在 .Net 2.0 中:
var myOddNums = myNums.FindAll(n => n%2==1);
但如果您确实有LINQ,那么保持延迟执行和立即执行之间的区别是很重要的。
如果我没记错的话,除了它们所实现的类型不同(IEnumerable<T>
vs. 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();
}
}
Where
函数表现更佳 - Eduardo A. Fernández Díaz