ilist c#




列表<T>或IList<T> (12)

任何人都可以向我解釋為什麼我想要在C#中使用列表中的IList?

相關問題: 為什麼公開List<T>被認為是不好的


IList <>幾乎總是比其他海報的建議更可取,但是請注意通過使用WCF DataContractSerializer進行多個序列化/反序列化運行IList <>時,.NET 3.5 sp 1中存在一個錯誤

現在有一個SP來修復這個bug: KB 971030


IList <T>是一個接口,所以你可以繼承另一個類,並繼續實現IList <T>,而繼承List <T>則阻止你這樣做。

例如,如果有一個類A並且你的類B繼承它,那麼你不能使用List <T>

class A : B, IList<T> { ... }

List<T>IList<T>一個特定實現,它是一個容器,可以使用整數索引以與線性數組T[]相同的方式進行尋址。 當您將IList<T>指定為方法參數的類型時,只能指定您需要容器的某些功能。

例如,接口規範不強制要使用的特定數據結構。 List<T>的實現發生與訪問,刪除和添加線性數組元素相同的性能。 但是,您可以想像一個由鏈接列表支持的實現,而最後添加元素的成本更低(恆定時間),但隨機訪問成本更高。 (請注意,.NET LinkedList<T>不實現IList<T> 。)

這個例子還告訴你,當你需要在參數列表中指定實現而不是接口時,可能會出現以下情況:在本例中,每當需要特定的訪問性能特徵時。 這通常可以保證容器的具體實現( List<T> documentation:“它使用大小根據需要動態增加的數組實現IList<T>泛型接口。”)。

另外,您可能需要考慮公開您需要的最少功能。 例如。 如果您不需要更改列表的內容,則應該考慮使用IList<T>擴展的IEnumerable<T>


界面可以確保你至少得到你所期望的方法 ; 意識到界面的定義即。 所有的抽象方法都要由繼承接口的任何類來實現。 所以如果有人用自己的一大類自己的幾個方法,除了從接口繼承的一些附加功能以外,還有一些方法對你沒有用處,那麼最好使用對子類的引用(在這種情況下,接口)並為其分配具體的類對象。

另外一個好處就是你的代碼對具體類的任何修改都是安全的,因為你僅僅訂閱了具體類的幾個方法,只要具體類繼承自你所在的接口,這些就會在那裡使用。 所以它為您和您的自由提供了安全保障,編寫者正在編寫具體的實現,為他的具體類更改或添加更多功能。


不太受歡迎的答案是程序員喜歡假裝他們的軟件將在世界範圍內重新使用,實際上大多數項目將由少量人員維護,然而不錯的界面相關的soundbite,你是騙子你自己。

建築宇航員 。 您將自己編寫自己的IList的機會添加到已經在.NET框架中的任何內容中,這些內容都非常遙遠,以至於它只能用於“最佳實踐”。

很明顯,如果你在面試中被問到你在使用什麼,你說IList,微笑,並且都很高興看到自己這麼聰明。 或者是面向公眾的API,IList。 希望你明白我的觀點。


你可以從多個角度看待這個觀點,包括純粹的面向對象方法的一種方法,該方法表示根據接口進行編程而不是實現。 有了這個想法,使用IList遵循與傳遞和使用從頭開始定義的接口相同的原理。 我也相信一般界面提供的可伸縮性和靈活性因素。 如果需要擴展或更改提供IList <T>的類,則消費代碼不必更改; 它知道IList接口合同遵守什麼。 但是,如果在具有更改的類上使用具體實現和List <T>,則可能導致調用代碼也需要更改。 這是因為遵循IList <T>的類保證了使用List <T>的具體類型無法保證的某種行為。

還有權力做類似修改List <T>的類的默認實現。實現IList <T>用於說.Add,.Remove或任何其他IList方法為開發人員提供了很大的靈活性和強大功能,否則預定義通過List <T>


假設這些List與IList問題(或答案)都沒有提到簽名差異。 (這就是為什麼我在SO上搜索這個問題!)

因此,這裡列出了在IList中找不到的方法,至少在.NET 4.5(大約在2015年)

  • 的AddRange
  • AsReadOnly
  • 二分查找
  • 容量
  • ConvertAll
  • 存在
  • 找到所有
  • FindIndex
  • FindLast中
  • FindLastIndex
  • 的ForEach
  • GetRange
  • InsertRange
  • LastIndexOf
  • 移除所有
  • RemoveRange
  • 相反
  • 分類
  • ToArray的
  • TrimExcess
  • TrueForAll

如果.NET 5.0將System.Collections.Generic.List<T>替換為System.Collections.Generic.List<T>會怎麼樣? .NET始終擁有名稱List<T>但它們保證IList<T>是合同。 因此,恕我直言,我們(至少我)不應該使用某人的名字(儘管它在這種情況下是.NET),並在以後出現問題。

在使用IList<T>情況下,調用者總是保證可以工作,並且實現者可以自由地將底層集合更改為IList替代具體實現


我會繞過這個問題,而不是證明你為什麼要在具體實現中使用接口,試圖證明你為什麼要使用具體實現而不是接口。 如果你不能證明它,請使用界面。


所有的概念基本上都是在上面關於為什麼在具體實現中使用接口的大部分答案中闡述的

IList<T> defines those methods (not including extension methods)

IList<T> MSDN鏈接

  1. 明確
  2. 包含
  3. 複製到
  4. 的GetEnumerator
  5. 指數
  6. 去掉
  7. RemoveAt移除

List<T>實現了這9種方法(不包括擴展方法),最重要的是它包含大約41種公共方法,這就考慮了在應用程序中使用哪種方法。

List<T> MSDN鏈接


通常,一種好的方法是在面向公眾的API中使用IList(如果適用,並且需要列表語義),然後在內部列表以實現API。 這使您可以更改為不同的IList實現,而不會破壞使用您的類的代碼。

類名List可能會在下一個.net框架中更改,但接口永遠不會因為接口是契約而改變。

請注意,如果您的API僅用於foreach循環等,那麼您可能需要考慮公開IEnumerable。


通過實現使用接口的最重要的情況是在API的參數中。 如果你的API接受一個List參數,那麼任何使用它的人都必須使用List。 如果參數類型是IList,則調用者有更多的自由,並且可以使用您從未聽說過的類,這些類在編寫代碼時甚至可能不存在。







generics