我想編寫一個運行在隊列式界面上的對象。我去尋找IQueue<T>
,但出乎意料地空手而回。爲什麼在.NET Framework中沒有IQueue <T>或IStack <T>接口?
主要有以下幾種收集相關的接口:
ICollection<T>
IList<T>
IDictionary<TKey,TValue>
ISet<T>
是什麼原因讓這些類型的集合得到定義良好的接口?爲什麼堆棧和隊列不能保證接口?
我想編寫一個運行在隊列式界面上的對象。我去尋找IQueue<T>
,但出乎意料地空手而回。爲什麼在.NET Framework中沒有IQueue <T>或IStack <T>接口?
主要有以下幾種收集相關的接口:
ICollection<T>
IList<T>
IDictionary<TKey,TValue>
ISet<T>
是什麼原因讓這些類型的集合得到定義良好的接口?爲什麼堆棧和隊列不能保證接口?
嗯,因爲從那些接口到實現它們的類會有一對一映射(最新的ConcurrentQueue
除外)。但是其他提到的接口有許多類來實現它們。
擴大一點。我們無法知道BCL團隊的真正動力。但我有一種感覺,當他們創建Queue
和Stack
時,這些類看起來非常微不足道,因此他們決定不將它們抽象爲接口。原因很明顯:類看起來非常簡單但同時完整,所以沒有理由在BCL中創建不同的實現。然後來到ConcurrentQueue
和以前的聲明變得稍微不正確。
因爲它指出Queue
和ConcurrentQueue
沒有那麼相似,使他們實現單一接口。
我認爲這是因爲堆棧和隊列是非常特殊的概念,據我所知沒有其他類實現堆棧或隊列的特殊形式。
編輯:
好了,現在有一個ConcurrentQueue<T>
,這似乎否定我的結論。也許,在C#1.0還處於測試階段的那些日子裏,語言設計者認爲永遠不會有一種特殊的隊列/堆棧形式,現在爲它引入接口爲時已晚。
這是很多猜測。我希望Eric Lippert會看到這個問題並發表一個「官方」聲明。 :-)
我想你沒有看到Stack或Queue接口是因爲集合的本質。您列出的具有接口的集合接口是隨機訪問,而堆棧和隊列則不是。它們必須以非常特殊的方式訪問(FIFO或LIFO),因此不能一般使用。因此,將這些集合用作泛型實現是有意義的,但不能通過接口。換句話說,由於LIFO/FIFO放在一個集合上的限制,實現理論IStack或IQueue的類可以完成很少(或沒有)。
要實現這個想法,你可以創建自己的IStack和/或IQueue,然後在課堂上實現它們。您將看到您公開的功能將完全通過。例如。您最終只需將請求和結果轉發或返回到內部的堆棧或隊列集合。在這種傳遞功能中,潛在的附加值幾乎沒有或幾乎沒有。
爲什麼應該 .NET框架有IQueue<T>
和IStack<T>
接口?他們會買什麼?
是什麼使這些類型的集合 獲得了定義良好的接口?
該基類庫實際使用所有這些接口(IList
等):在每種情況下,有一堆爲它更有意義比一個具體類型的接口的抽象相互作用的其它類。
爲什麼堆棧和隊列不保證 接口?
大概是因爲沒有那個必要IStack<T>
和IQueue<T>
並沒有明顯的或可能的使用-情況下,這些抽象的任何BCL類。我認識到這不是一個令人滿意的哲學答案,但它看起來像框架設計師真的很注重界面的功能:當他們需要它們時,他們做出了界定。
我懷疑是否有任何特別的原因。如果我有我的druthers,那麼即使沒有獨立實現它們的類,也會有更多離散定義的接口。例如,我可能已經實現了QueueStack(Of T),它將實現IGetNext(Of T),IGetNextWait(Of T)和IClear(Of T),以及IQueue(Of T),IWaitQueue(Of T), IStack(Of T)和IWaitStack(Of T)。消費對象的人可以狹義地指定他們真正需要的東西,實施者只需要實現他們聲稱支持的東西。
我認爲.NET 4 ConcurrentQueue<T>
和ConcurrentStack<T>
中新類的存在證明了你的觀點,即應該有IQueue<T>
和IStack<T>
接口。即使它們本來不存在,也應該在.NET 4中添加它們。
我不得不在.NET中創建自己的自定義Stack實現,並同意擁有標準接口會有好處。
堆棧或隊列是一個相當簡單的排序列表實現,那麼爲什麼它們會像2行代碼一樣構建,以便它可以代替1? – 2010-12-06 15:25:12
@Russell Steen在隊列中排序*是什麼?鏈接列表可能是? – Andrey 2010-12-06 15:27:25
@Russell Steen實現細節不應該是具有明確定義的*接口*的一個因素。 – 2010-12-06 15:33:35