2016-11-16 63 views
-2

我想在c#中使用Linq過濾一個列表,如下所示?C#使用Linq過濾列表需要調用ToList方法嗎?

// Returns a List<Person> 
var personList = getPersons(); 

if (!string.IsNullOrEmpty(PersonName.Text)) 
    personList = personList.Where(x => x.Name.Contains("Joe")); 

,但我得到的錯誤:

Cannot convert source type 'System.collections.Generic.Ienumerable<Mysite.Models.Person>' to target type 'System.collection.Generic.List<Mysite.Models.Person> 

我必須做到以下幾點來解決,即添加ToList()

personList = personList.Where(x => x.Name.Contains("Joe")).ToList(); 

我的問題是,爲什麼我需要調用ToList時personList已經是類型List<Person>的列表?

+8

因爲'Where'不返回一個列表,它基本上只是返回的查詢,而不是一個集合。如果你將personList聲明爲「IEnumerable 」,它也會被編譯。 –

+0

@Tim getPersons()方法返回一個List,因此無法將其更改爲IEnumerable。同樣的事情會發生,如果我沒有使用lambda表達式,即做類似於'從p在personList'其中p.name =='Joe'選擇p' – adam78

+1

列表實現IEnumerable 所以你只需要用IEnumerable替換var

回答

1

Where返回IEnumerable<T>並且getPersons()方法返回List<Person>。您可以用List<T>代替IEnumerable<T>,但不能相反。

至於如何解決它,這取決於。如果要在Person集合上使用List<T>中的方法,則調用.ToList()是處理該方法的正確方法,例如.ForEach()

另一方面,如果您不需要List<T>中的任何方法/屬性,則可以聲明該變量爲IEnumerable<Person> personList = getPersons();或更改返回類型getPersons()

From MSDN

[SerializableAttribute] 
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, 
IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T> 
+0

即使你不需要'List '的方法,你應該在應用所有的過濾器時調用ToList。所以不是每次你打電話給'Where',而是在最後。否則,當您觸摸序列時,您總是會執行查詢。 –