我经常想检查提供的值是否与列表中的值匹配(例如在验证时):
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
最近,我注意到ReSharper要求我将这些查询简化为:
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
显然,这在逻辑上是相同的,也许可读性稍强(如果您做了大量的数学运算),我的问题是:这会导致性能下降吗?
感觉它应该(即. any()听起来像短路,而. all()听起来像没有),但我没有任何证据来证实这一点。有没有人有更深层次的知识,是否查询将解决相同的,或者ReSharper是否引导我误入歧途?
你可能会发现这些扩展方法使你的代码更具可读性:
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
}
如果你看一下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;
}
一种方法不可能明显比另一种方法快,因为唯一的区别在于布尔否定,所以更喜欢可读性而不是虚假性能。