我经常想检查提供的值是否与列表中的值匹配(例如在验证时):

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

最近,我注意到ReSharper要求我将这些查询简化为:

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

显然,这在逻辑上是相同的,也许可读性稍强(如果您做了大量的数学运算),我的问题是:这会导致性能下降吗?

感觉它应该(即. any()听起来像短路,而. all()听起来像没有),但我没有任何证据来证实这一点。有没有人有更深层次的知识,是否查询将解决相同的,或者ReSharper是否引导我误入歧途?


当前回答

根据这个链接

Any -检查至少一个匹配 All -检查所有匹配

其他回答

All()确定序列的所有元素是否满足条件。 Any()确定序列中的任何元素是否满足条件。

var numbers = new[]{1,2,3};

numbers.All(n => n % 2 == 0); // returns false
numbers.Any(n => n % 2 == 0); // returns true

如果你看一下Enumerable源代码,你会发现Any和All的实现非常接近:

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;
}

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;
}

一种方法不可能明显比另一种方法快,因为唯一的区别在于布尔否定,所以更喜欢可读性而不是虚假性能。

正如其他答案所涵盖的那样:这与性能无关,而是与清晰度有关。

你的两个选择都得到了广泛的支持:

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

但我认为这可能会获得更广泛的支持:

var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
    // exception logic
}

在否定任何东西之前简单地计算布尔值(并命名它)在我的脑海中清晰了很多。

两者将具有相同的性能,因为两者都在可以确定结果后停止枚举—传递的谓词对第一项的Any()计算为true,而谓词对第一项的All()计算为false。

根据这个链接

Any -检查至少一个匹配 All -检查所有匹配