List<>.FindAll带有多个条件

4
有没有比这更快的方法来查找具有某些条件的所有人员?
if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname) && !String.IsNullOrEmpty(phone))
{
      List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname && s.Phone == phone);
}
else if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname))
{
      List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname);
}

etc.


可能需要使用循环,尽管匹配越多,所需时间就越长(不匹配更快)。 - Charleh
1
数据来自哪里?它是否总是在内存中?您是从数据库等地方访问吗? - RQDQ
2
你真的需要更快的速度,还是只是更容易维护? - Reed Copsey
2个回答

7
您的版本很可能是运行时最快的选项。您创建的 List<T>.FindAll 谓词非常有效,因为它进行了最少的检查。
然而,您可以使用 LINQ 使代码更简洁、更易于维护:
IEnumerable<Person> people = List; // Start with no filters

// Add filters - just chaining as needed
if (!string.IsNullOrWhitespace(name) && !string.IsNullOrWhitespace(lastname))
{
    people = people.Where(s => s.Name == name && s.Surname == lastname);
    if (!string.IsNullOrWhitespace(phone))
        people = people.Where(s => s.Phone == phone);
}

//... Add as many as you want

List<Person> newList = people.ToList(); // Evaluate at the end

这样更易于维护,并且很可能足够快,因为过滤通常不是在一个紧密的循环中完成。


我也会使用类似于PredicateBuilder(http://www.albahari.com/nutshell/predicatebuilder.aspx)的工具来构建过滤表达式。 - Preston Guillot
@PrestonGuillot 这都是内存中的操作,所以不需要这个。话虽如此,使用 EF 等标准查询器应该同样有效。PredicateBuilder 很好用,但仅适用于需要从字符串构建过滤器,而非从已知变量名称的代码构建。 - Reed Copsey
@PrestonGuillot PredicateBuilder 对于这个问题有点过头了。你可以在一个 if 块中更改查询,因为两者都评估为 IQueryable<Person> / IEnumerable<Person> - Simon Belanger
请注意:这个版本执行的功能与原来的不同。 - Chris Pitman
@ChrisPitman 好观点 - 现在已经使结果与原始结果相同。 - Reed Copsey

3

我会重新撰写这篇文章,使其更易于阅读:

if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname)) {
     if (!String.IsNullOrEmpty(phone))
     {
           List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname && s.Phone == phone);
     }
     else 
     {
          List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname);
     }
}

+1 这也避免了在原始帖子的else if中重新评估namelastname的空/空检查。 - mlorbetske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接