1.引用MSDN的Any
Enumerable.Any<TSource>方法 (IEnumerable<TSource>, Func<TSource, Boolean>)
確定序列中的任何元素是否都滿足條件。
命名空間: System.Linq
程序集:System.Core(在 System.Core.dll 中)語法
類型參數
- TSource
source 中的元素的類型。
參數
- source
- 類型: System.Collections.Generic.IEnumerable < TSource >
一個 IEnumerable<T>,其元素將應用謂詞。
- predicate
- 類型: System.Func < TSource, Boolean >
用於測試每個元素是否滿足條件的函數。使用說明
在 Visual Basic 和 C# 中,可以在 IEnumerable < TSource >類型的任何對象上將此方法作為實例方法來調用。當使用實例方法語法調用此方法時,請省略第一個參數。有關更多信息,請參見 擴展方法 (Visual Basic)或 擴展方法(C# 編程指南)。備注
說明
此方法不返回集合的任何一個元素。而是確定集合的任何元素是否滿足某一條件。
一旦可確定結果,則停止枚舉 source。
2.解讀與誤讀
以上是MSDN的備注,一直用All,在思想上,已向 All 靠攏。 All的理解是: 進行遍歷, 回調返回 false 則停止遍歷 。 返回值 = 最后回調的返回值(序列為空,返回true)。 基本上用All 可以實現 Any 所有的事。
但它們返回值和執行機制不同, Any 不延遲執行。 而All 是延遲執行的。 (它們都是即時執行)
現在說說MSDN的解釋,仔細讀讀Any的MSDN解釋,就發現它有多么不可理解。
1. 確定序列中的任何元素是否都滿足條件。
上面說的不是人話,是計算機話,人理解需要解讀: 如果返回 true , 表示 序列中的所有元素全部滿足條件 。 如果返回false,表示序列中存在不滿足條件的元素。
誤讀:返回true,表示序列中的所有元素全部滿足條件。 如果返回false,表示序列中的元素全部不滿足條件 。那,部分滿足,部分不滿足,又如何呢? 自己跟自己說不通。
2. predicate 用於測試每個元素是否滿足條件的函數。
解讀:嗯。如果返回true,表示該元素滿足條件, 如果返回false,表示該元素不滿足條件 。
根據1 的理解, 返回true,要繼續執行。 返回false 要停止執行。
3. 返回值: 如果源序列中的任何元素都通過指定謂詞中的測試,則為 true;否則為 false
解讀: 如果回調全部返回true,則返回true, 否則返回false。 根據 2的理解,返回一個 false 就要停止 ,所以,它返回的還是最后一次回調返回值。
4.最后一句, 一旦可確定結果,則停止枚舉 source。
解讀: 一旦確定true結果,則停止枚舉srouce 。
誤讀: 一旦確定 false 結果,是不是也算是確定結果?!!! 那豈不成了只判斷第一個了嗎。 自己跟自己又說不通。
3.驗證得到正確理解
理解上的沖突出現了,就在於 “任何” 這兩個字上。 查查詞典: http://cd.kdd.cc/I/FQ/ 里面的有英語單詞的翻譯: 任何= Any. 很明顯的,翻譯濫用了”任何“
舉兩個”任何“的例子來理解: 如 "任何人不得入內“,”任何人都可以進來“ 。
經代碼驗證,上面的理解,2,4 是正確的。
string[] str = new string[] { "a", "abc", "b" }; var d = str.Any(o => { Console.WriteLine(o); return o.Length > 1; }); Console.WriteLine(d);
上面輸出:
a
abc
True
正確對Any的理解: 進行遍歷,回調返回 true 即停止遍歷,返回值=最后回調的返回值(序列為空,返回 false)
4.分析濫用行為
對比All,確認,All 可以做 Any 的任何事情。 下面分析濫用行為:
濫用1: 確定序列中的任何元素是否都滿足條件。
可能是機器翻譯的結果。 應該是 確定序列中是否存在滿足條件的任一元素。
濫用2:返回值: 如果源序列中的任何元素都通過指定謂詞中的測試,則為 true;否則為 false
有任何一個通過,就停止遍歷, 何談任何元素通過測試? 應該是: 如果有任一元素通過測試,則為true,否則為false。
這也是大家對MSDN的Linq,弄不明白的地方之一,看MSDN看不明白,總是通過其它開發者的解讀和測試來達到自己的理解的原因。