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看不明白,总是通过其它开发者的解读和测试来达到自己的理解的原因。