2013-07-09 56 views
4

有一些比這更快的方法來找到所有有條件的人?List <>。FindAll很少有條件

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); 
} 

+0

可能,使用循環,但你得到的越久越匹配,這將需要(這是更快地不匹配) – Charleh

+1

在哪裏數據來自哪裏?它總是在記憶中嗎?你是從數據庫訪問等? – RQDQ

+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 

這會更易於維護,而且可能是「不夠快」,因爲如果過濾通常不會在緊張進行循環。

+0

我也使用'PredicateBuilder'(http://www.albahari.com/nutshell/predicatebuilder.aspx)來構建過濾器表達式。 –

+0

@PrestonGuillot這是所有內存中的,所以不需要。這就是說,使用EF和類似的標準查詢語言應該同樣有效。 PredicateBuilder是很好的,但只有當你需要從字符串構建過濾器時,而不是從具有已知變量名稱的代碼構建。 –

+0

@PrestonGuillot PredicateBuilder對這個問題有點矯枉過正。你可以在'if'塊中改變查詢,因爲它們都是以'IQueryable '/'IEnumerable '爲結果。 –

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); 
    } 
} 
+0

+1它也避免了重新評估原始帖子中else if的'name'和'lastname'的空/空檢查 – mlorbetske

相關問題