簡體   English   中英

來自List的無效演員表 <MyType> 到IEnumerable <MyType> 返回目錄 <MyType> ,為什么?

[英]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

此外,以這種方式實現它更容易。 想象一下,你必須寫一個時刻WhereIList 哪個必須返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM