[英]Invalid cast from List<MyType> to IEnumerable<MyType> back to List<MyType>, why?
所以基本上我有這個方法。
public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
return (List<Customer>)source.Where(c => c.Status == status);
}
我拋出一個它無法投射的錯誤:
無法將類型為'WhereListIterator`1 [AppDataAcces.Customer]'的對象轉換為'System.Collections.Generic.List`1 [AppDataAcces.Customer]'。
為什么...? 由於底層類型是相同的,Enumerable.Where是否創建了WhereListIterator的新實例,如果是這樣,為什么有人會這樣做,因為這是不必要的性能和功能損失,因為我總是要創建一個新列表(.ToList( ))
是Enumerable.Where創建
WhereListIterator
的新實例
是。
如果是這樣,為什么有人會這樣做
因為它允許懶惰的流式傳輸行為。 Where
不會有如果消費者只想要第一或第二項過濾所有的名單。 這對LINQ來說是正常的。
因為這總是不得不創建一個新的列表(.ToList()),這是不必要的性能和功能損失
“性能和功能的損失”來自您的設計。 過濾后不需要List<Customer>
,因為對它進行任何修改都沒有意義。
更新:“為什么這樣實現”因為它是通過IEnumerable
實現的,而不是IList
。 因此它看起來像IEnumerable
,它像IEnumerable
一樣IEnumerable
。
此外,以這種方式實現它更容易。 想象一下,你必須寫一個時刻Where
過IList
。 哪個必須返回IList
。 它該怎么辦? 在原始列表上返回代理? 每次訪問都會遭受巨大的性能損失。 返回包含已過濾商品的新列表? 它與Where().ToList()
。 返回原始列表但刪除了所有不匹配的項目? 這就是RemoveAll
的用途,為什么要制作另一種方法。
請記住,LINQ嘗試播放功能,並嘗試將對象視為不可變的。
正如其他人所指出的,您需要使用ToList
將結果轉換為List<T>
。
原因是懶惰地評估了Where
,所以Where
沒有真正過濾數據。 它的作用是創建一個IEnumerable
,根據需要過濾數據。
懶惰評估有幾個好處。 它可能更快,它允許使用Where
無限IEnumerable
s等。
ToList
強制將結果轉換為List<T>
,這似乎是你想要的。
Where擴展過濾並返回IEnumerable<TSource>
因此您需要調用.ToList()將其轉換回來
public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
return source.Where(c => c.Status == status).ToList();//This will return a list of type customer
}
IEnumerable和IList之間的區別在於,可枚舉不包含任何數據,它包含一個迭代器 ,當您請求新數據時它會遍歷數據(例如,使用foreach循環)。 另一方面,列表是數據的副本。 在您的情況下,要創建List,ToList()方法將遍歷整個數據並將它們添加到List對象。
根據您計划的用途,兩者都有優點和缺點。 例如,如果您計划多次使用整個數據,則應該使用該列表,但如果您計划使用它一次或計划使用linq再次查詢,則應該選擇enumerable。
編輯:為什么返回類型Where WhereListIterator而不是List的問題的答案,部分是因為Linq如何工作。 例如,如果您在第一個之后有另一個Where或另一個Linq語句,則編譯器將使用整個方法鏈創建單個查詢,然后返回最終查詢的迭代器。 另一方面,如果第一個Where將返回一個List,它將導致鏈中的每個Linq方法分別對數據執行。
試試這個:
public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
return source.Where(c => c.Status == status).ToList();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.