2012-01-19 52 views
41

哪有我投了List<object>List<SomethingElse>如何投放列表<object>爲List <SomethingElse>

其中SomethingElse被稱爲從object下降)


獎金看點

鑄造名單:

List<Object> first = ...; 

List<SomethingElse> second = (List<SomethingElse>)first; 

不起作用:

不能鍵入 'System.Collections.Generic.List' 轉換爲 'System.Collections.Generic.List'

鑄造名單:

List<SomethingElse> second = first.Cast<SomethingElse>(); 

不起作用:

無法將類型'System.Collections.Generic.List'隱式轉換爲'System.Collections.Generic.List'

其實我並不需要完整的List<T>對象,只是一個ICollection<T>會做:

ICollection<SomethingElse> second = first; 
ICollection<SomethingElse> second = (ICollection<SomethingElse>)first; 
ICollection<SomethingElse> second = first.Cast<SomethingElse>(); 

不起作用。

+0

相關? http://stackoverflow.com/questions/1266014/c-sharp-casting-a-listobjbase-as-listobj – eldarerathis

+0

可能的重複http://stackoverflow.com/questions/7955890/how-to-cast-listclassb-to -listclassa-when-classb-inherits-from-classa – dash

+0

這個工作嗎? List second = first.Select(o =>(SomethingElse)o).ToList(); – asmo

回答

31

LINQ,如通過Enumerable類內的擴展方法來實現,依賴於延遲執行:即在返回值的序列不消耗目標數據,直到所述查詢的查詢中使用

方法枚舉對象。這被稱爲延期執行。

Cast<T>不立即創建新列表,而是存儲執行該操作所需的所有信息。該列表只會在需要時列舉(例如,通過foreach聲明)。

在你的情況,如果你只是打算遍歷序列,你應該考慮堅持到IEnumerable<T>接口,這是Cast<T>聲明返回類型:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>(); 
foreach (SomethingElse se in second) 
{ 
    // ... 
} 

這是有效的,因爲它只當每個項目被迭代時執行演員陣容。

如果你確信你想立即創建一個新的列表,使用ToList

List<SomethingElse> second = first.Cast<SomethingElse>().ToList(); 

編輯:答覆點張貼評論:

這取決於你是什麼意思通過「可以修改的列表」。有幾個LINQ查詢運算符將允許您進一步更改查詢的定義。例如,如果你想刪除所有SomethingElse元素,其IsDeleted屬性是true,你可以使用Where操作:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>(); 
second = second.Where(element => !element.IsDeleted); 

如果要添加新的元素序列,您可以使用Concat操作:

second = second.Concat(anotherCollectionOfSomethingElse); 

如果要排序你在ID升序排列順序,使用OrderBy操作:

second = second.OrderBy(element => element.ID); 

每一次,我們都將查詢操作符應用於查詢的前一個定義,並將新的(複合)查詢分配給我們的second變量。 LINQ會將所有的操作符存儲在查詢定義中。然後,當序列實際枚舉時(例如,通過foreachToList),它會爲您提供序列的組合結果,並按順序應用所有查詢運算符。

與延期執行/懶惰評估的所有情況一樣,請注意不要過分執行此操作。例如,如果你打算申請一個Where運算符,這會大大減少你的序列的大小,那麼可能會急切地執行查詢並存儲枚舉列表。

+0

我不需要立即創建一個新列表;但我確實需要一個可以修改的列表,並且不受協方差問題的限制。如果ToList是我需要的,那麼我需要使用它。當然,我會更喜歡返回的'List'是'first'的一個包裝,允許推遲執行。 –

13

我認爲你接近Cast<T>表達式。區別在於Cast<T>返回IEnumerable<T>,而不是List<T>

試試這個:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>(); 

你可以做類似的事情得到一個列表:

List<SomethingElse> second = first.Cast<SomethingElse>().ToList(); 
9

可以選擇使用CastOfType的選項。如果你不能轉換爲指定的類型,那麼Cast會拋出異常。另一方面,OfType將只返回列表中可以轉換爲指定類型的那些項目。我會建議在您的情況下使用OfType

List<Foo> fooList = myList.OfType<Foo>().ToList(); 
相關問題