2010-07-22 82 views
0

作爲將IList<T1>轉換爲IList<BaseT1>的最簡單方法?將IList <T1>轉換爲IList <BaseT1>

IList<T1>.Count()是非常大的數字!

class BaseT1 { }; 
class T1 : BaseT1 
{ 
    static public IList<BaseT1> convert(IList<T1> p) 
    { 
     IList<BaseT1> result = new List<BaseT1>(); 
     foreach (BaseT1 baseT1 in p) 
      result.Add(baseT1); 
     return result; 
    } 
} 
+0

的IList = System.Collections.Generic.IList – SkyN 2010-07-22 16:57:35

回答

3

linq?

var baseList = derivedList.Cast<TBase>(); 

編輯:

Cast返回一個IEnumerable,你需要它的ListList可以是一個昂貴的類來處理

+0

的IList = System.Collections.Generic.IList – SkyN 2010-07-22 16:57:52

+1

'.ToList()'... – BrunoLM 2010-07-22 17:08:11

3

如果指定當initalized的result列表的大小,並調用Add方法上List<T>直接你會得到你實現更好的性能:

List<BaseT1> result = new List<BaseT1>(p.Count); 

這樣,它添加新項目時不會調整大量數組的大小。這應該會產生一個數量級的加速。

或者,您可以編寫一個包裝類,它實現了IList<BaseT1>並在構造函數中使用了IList<T1>

+0

爲什麼甚至使用列表?只是使用收益回報 – 2010-07-22 16:56:07

+1

因爲他希望在'IList '中,而不是'IEnumerable '。 Linq不是一切的答案。 – thecoop 2010-07-22 16:56:49

+0

正要糾正;你太快了! – 2010-07-22 16:57:07

3
IList<T1>.Count() is very large number!!! 

是的,這意味着無論您使用什麼糖語法,轉換都需要O(n)時間和O(n)存儲。您不能轉換列表以避免重新創建它。如果可能的話,客戶端代碼可能會將BaseT1的元素添加到列表中,違反了列表中只包含與T1兼容的對象的承諾。

要想領先的唯一方法是返回無法更改列表的接口類型。在這種情況下,這將是IEnumerable<BaseT1>。允許你迭代列表,沒有別的。這種轉換在.NET 4.0中是自動的,這要歸功於它對協方差的支持。你必須寫在早期版本的一點膠水代碼:

public static IEnumerable<BaseT1> enumerate(IList<T1> p) { 
     foreach (BaseT1 item in p) yield return item; 
    } 
相關問題