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

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

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

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

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

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


当前回答

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

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

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
}

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

其他回答

第一次不匹配都是短路,所以没问题。

一个微妙的地方是

 bool allEven = Enumerable.Empty<int>().All(i => i % 2 == 0); 

是真的。序列中的所有项都是偶数。

有关此方法的更多信息,请参阅Enumerable.All的文档。

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

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

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

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
}

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

你可能会发现这些扩展方法使你的代码更具可读性:

public static bool None<TSource>(this IEnumerable<TSource> source)
{
    return !source.Any();
}

public static bool None<TSource>(this IEnumerable<TSource> source, 
                                 Func<TSource, bool> predicate)
{
    return !source.Any(predicate);
}

现在不是你原来的了

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

你可以说

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

根据这个链接

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