2011-10-04 50 views
9

如果我在郵件列表的發佈/訂閱架構,我認爲它是合理使用IEnumerable.Where在底層列表檢索特定的消息,並相信消息的順序?是LINQ擴展方法在哪裏保證維護秩序?

+0

請注意,實際上沒有任何「IEnumerable.Where」這樣的方法。有一個'Enumerable.Where'擴展方法,它接受'IEnumerable '。但是給定的LINQ查詢完全有可能對給定的枚舉類型使用不同的東西!它可以以保持順序或無順序保存的方式實現。 –

+0

我知道這不是一個成員,而是一種擴展方法。這只是更容易編寫,我假定每個人都知道linq擴展方法。 – LinusK

+0

請記住,給定的枚舉類型可能會定義自己的Where()方法,該方法可能用於替代Enumerable.Where(),具體取決於您列舉的引用的類型。 –

回答

20

Enumerable.Where擴展方法,但Queryable.Where擴展方法的習慣。

Enumerable.Where具有保留的順序的,因爲它流的結果,並沒有緩存(且在高速緩存的結果沒有邏輯)。

Queryable.Where另一方面將給定的查詢翻譯爲底層數據源將理解的內容,並且不能保證如此排序。使用關係數據庫時,可以輕鬆觀察到這種效果。增加一個where子句可以讓數據庫選擇另一個索引,這可以改變結果的排序。

+0

事實上,LINQ到實體被記錄後,*不*爲了保持一個'。凡()' –

+4

雖然這是真的,'Enumerable.Where'目前保持秩序,我沒有看到任何保證它將接口文檔中。當然,如果你使用'ParallelEnumerable',所有的注單都關閉。 –

+1

@Jim:我同意的'Enumerable.Where'沒有說明它將維持秩序的文件,但我認爲它是安全的假設,它會永遠保留排序,因爲它仍然是一個相當大的行爲改變,很多開發者依賴。 – Steven

7

對於Linq to Objects/IEnumerable這是事實 - 訂單將保持不變 - 對於IQueryable供應商而言,它取決於供應商,許多供應商不維護訂單。

它看起來像這樣的事實(維持秩序)是不是在MSDN上記錄的,所以我會考慮它的實現細節 - 雖然可能性不大 - 可能會在未來改變。

+0

是否記錄了IEnumerable接口以保持順序?或者我們只是「知道」它會? –

+0

@Jim,'IEnumerable'根本沒有'Where'。這是一個擴展方法和查詢模式,但它不是接口的成員。 –

+0

@CraigStuntz:很好。那麼'Enumerable.Where'。我沒有看到說它會保持秩序的文件。 –