[英]Should we use ICollection<T> in the Interface and Collection<T> in the class?
[英]Collection<T> class and it's use
我遇到了以下代碼:
var collection = new Collection<string>();
我沒有看到Collection類使用太多,也找不到太多關於它的用途的信息。 查看.NET Framework源代碼,它幾乎只是List的包裝器,因為它存儲了List成員字段。 它的構造函數如下:
public Collection()
{
this.items = (IList<T>) new List<T>();
}
它還實現了IList。 所以你可以將Collection聲明為:
IList<string> collection = new Collection<string>();
對我來說,在功能上等同於創建一個List:
IList<string> collection = new List<string>();
那么你什么時候想在你自己的代碼中使用它? 我看到它是其他.NET集合的基類,但為什么它們將它作為公共具體 (而不是內部和/或抽象)包含在內?
關於可能重復的注釋 - 相關問題的答案似乎表明Collection類應該用作基類。 我真正要求的不同之處是:
我認為MSDN文檔本身已經列出了最重要的方面(由我強調):
集合類提供了可添加時和移除項,清除集合或設置現有項目的價值來 定制其行為 受保護的方法 。
和
對實施者的說明
提供此基類是為了使實現者更容易創建自定義集合。 鼓勵實施者擴展此基類,而不是創建自己的基類。
[編輯ypur更新問題]
1.如果在您自己的代碼中使用,為什么不使用List作為基類呢?
Collection<T>
提供了一些受保護的方法,因此您可以輕松override
行為並完全注冊您自己的業務邏輯,例如:
ClearItems()
InsertItem()
RemoveItem()
SetItem()
List<T>
不提供它們,並且幾乎沒有用於覆蓋行為的受保護方法,這使得自定義更難。
2.在您自己的代碼中使用List初始化新集合是否真的有意義?
不,不只是為了初始化一些集合。 如果您需要它作為實現自己的邏輯的基類,請使用它。
這取決於您自己的業務需求。 對於日常開發工作中的幾乎所有情況,現有的和眾多的集合應該已經提供了您所需要的。 有類型安全和無類型集合,線程安全集合,以及您能想到的任何其他內容。
盡管如此,有一天可能需要實現一種集合類型,該集合類型在允許添加/更新/刪除其中的任何項目之前執行某些驗證檢查,或者以特定方式處理僅在稀疏填充的列表中移動到下一項目。 你永遠不知道顧客可能有什么想法。
在這種情況下,創建自己的集合類型可能會有所幫助。
Collection(T)類是一大堆其他集合類的基類。 List類是針對速度進行優化的類,而Collection類是為可擴展性而設計的。
當您查看Collection(T)
的成員時,您將看到它包含List(T)
類沒有的一些其他受保護的虛擬方法(如InsertItem
)。
實際上,我已經創建了Collection類的一個實例。 我想我只會將此類型用作方法簽名中的參數,只是為了不將方法與集合的實現緊密耦合(如果可能)。
回答你的問題:
我會使用Collection(T)
作為基類,因為該類的目的是用作其他集合類型的基類。 它為您提供了更大的靈活性(請參閱受保護的虛擬方法InsertItem
, RemoveItem
和SetItem
)
當需要集合時,我將使用List(T)
類的實例,因為它針對速度進行了優化。
實際上,我想知道為什么他們沒有將Collection(T)
類抽象化。
正如Krzysztof Cwalina 所說 :
•列表不是為了擴展而設計的。 即你不能覆蓋任何成員。 例如,這意味着在修改集合時,無法通知從屬性返回List的對象。 Collection允許您覆蓋SetItem受保護的成員,以便在添加新項目或更改現有項目時獲得“通知”。
•列表中有許多成員在許多情況下都不相關。 我們說List對於公共對象模型來說太“忙”了。 想象一下ListView.Items屬性返回List的所有豐富性。 現在,看看實際的ListView.Items返回類型; 它更簡單,類似於Collection或ReadOnlyCollection。
因此,FxCop的規則CA1002也告訴您不要公開通用列表並改為使用Collection。 另請參閱此代碼分析團隊博客文章,了解有關FxCop規則以及返回Collection而不是List的原因。
因此,對於問題1和2,請參見上文。 至於問題三,它不僅僅是作為一個基類。 你應該能夠實例化它並將其用作返回類型,因此它不是抽象的。
盡管枚舉接口提供了對集合的僅向前迭代,但它們不提供確定集合大小,通過索引訪問成員,搜索或修改集合的機制。 對於此類功能,框架提供ICollection
, IList
和IDictionary
接口。
ICollection<T>
提供中等功能(例如Count
屬性)。
IList<T>
及其非泛型版本提供最大功能(包括索引的“隨機”訪問)。
您很少需要實現任何這些接口。 幾乎在所有情況下,當您需要編寫集合類時,您可以改為繼承Collection<T>
等。
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.