考虑使用空白数组的linq示例:
当Any()
返回false
因为没有大于零的数字时,All()
如何返回true
传达所有大于零的数字?
var arr = new int[] { };
Console.WriteLine(arr.Any(n => n > 0)); //false
Console.WriteLine(arr.All(n => n > 0)); //true
答案 0 :(得分:58)
对我来说似乎很合乎逻辑。
All
:arr
中的所有数字是否大于零(意味着没有数字不更大比零)=> true
Any
:arr
中的任何号码是否大于零=> false
但更重要的是,根据Boolean Algebra:
arr.All(n => n > 0);
给出true
,因为它应该是
arr.Any(n => !(n > 0));
给出false
(实际上这就是上面两点所说的)。
答案 1 :(得分:24)
All
的实施非常清楚地显示了原因。
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (!predicate(element)) return false;
}
return true;
}
它在集合上运行foreach
。如果集合中没有元素,它将跳过foreach
并返回true。
有趣的是,Any
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (predicate(element)) return true;
}
return false;
}
这个清晰显示他们是对立的。
答案 2 :(得分:5)
All
的The implementation将返回true:
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (!predicate(element)) return false;
}
return true; // watch this
}
这似乎非常违反直觉,但这是如何实施的。
然而,文档对于All
的返回值非常清楚:
如果源序列的每个元素都通过了测试,则为true 指定的谓词,或如果序列为空;
答案 3 :(得分:3)
一些数学观点:
Any
和All
是||
和&&
运算符的通用版本,就像Sum
和Product
(不在LINQ中)是{的一般化{1}}和+
。
处理空集的返回neutral element时的广义运算符。对于*
,这是0,对于+
,这是1 *
,因为1是emptyArray.Product() == 1
操作的中性元素(对于所有a:*
), a * 1 == a
这是||
(false
),而a || false == a
这是&&
(true
)。
由于这种广义的操作符保留了&#34;原始&#34;的关联性。操作,例如求和:a || true == a
,即使其中一个intersect(A,B) == EmptySet; S = union(A,B); S.Sum() == A.Sum() + B.Sum()
或A
为空,这也会有用。换句话说,在数组上方便定义空集上的广义运算符返回中性元素。