簡體   English   中英

采集 <T> 上課和它的使用

[英]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類應該用作基類。 我真正要求的不同之處是:

  1. 如果在您自己的代碼中使用,為什么不使用List作為基類呢?
  2. 在您自己的代碼中實例化一個新的集合代替List真的有意義嗎?
  3. 如果真的只是作為基類提供, 為什么它不是抽象的

我認為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類的一個實例。 我想我只會將此類型用作方法簽名中的參數,只是為了不將方法與集合的實現緊密耦合(如果可能)。

回答你的問題:

  1. 我會使用Collection(T)作為基類,因為該類的目的是用作其他集合類型的基類。 它為您提供了更大的靈活性(請參閱受保護的虛擬方法InsertItemRemoveItemSetItem

  2. 當需要集合時,我將使用List(T)類的實例,因為它針對速度進行了優化。

  3. 實際上,我想知道為什么他們沒有將Collection(T)類抽象化。

正如Krzysztof Cwalina 所說

•列表不是為了擴展而設計的。 即你不能覆蓋任何成員。 例如,這意味着在修改集合時,無法通知從屬性返回List的對象。 Collection允許您覆蓋SetItem受保護的成員,以便在添加新項目或更改現有項目時獲得“通知”。

•列表中有許多成員在許多情況下都不相關。 我們說List對於公共對象模型來說太“忙”了。 想象一下ListView.Items屬性返回List的所有豐富性。 現在,看看實際的ListView.Items返回類型; 它更簡單,類似於Collection或ReadOnlyCollection。

因此,FxCop的規則CA1002也告訴您不要公開通用列表並改為使用Collection。 另請參閱此代碼分析團隊博客文章,了解有關FxCop規則以及返回Collection而不是List的原因。

因此,對於問題1和2,請參見上文。 至於問題三,它不僅僅是作為一個基類。 你應該能夠實例化它並將其用作返回類型,因此它不是抽象的。

我真的不喜歡回答我自己的問題,但就第三季而言,我相信我理解這個推理。 我看到Bas Paap的答案中提到的這個鏈接時得到了它。

簡而言之,Collection類不是抽象的原因是因為您可能希望自己選擇在以后從類派生。 在此期間,您可以將其用作返回類型並直接實例化它。 該鏈接顯示了一個代碼示例,在這種情況下。

我提出了所有其他答案,我認為這些答案解決了問題中提出的問題。

盡管枚舉接口提供了對集合的僅向前迭代,但它們不提供確定集合大小,通過索引訪問成員,搜索或修改集合的機制。 對於此類功能,框架提供ICollectionIListIDictionary接口。

ICollection<T>提供中等功能(例如Count屬性)。

IList<T>及其非泛型版本提供最大功能(包括索引的“隨機”訪問)。

您很少需要實現任何這些接口。 幾乎在所有情況下,當您需要編寫集合類時,您可以改為繼承Collection<T>等。

我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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