有时我希望有一定范围的项目,需要进行一些验证以确保我在该范围内.最明显的方法是将集合中的项目数与范围进行比较.
public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
return enumerable.Count() <= max;
}
Run Code Online (Sandbox Code Playgroud)
虽然,我的理解是linq Count()方法将在返回结果之前评估整个可枚举.理想情况下,我只会对最小数量的项目进行评估以获得我的结果.
在不引起任何不必要评估的情况下,确保可枚举项目少于一定数量的最佳方法是什么?
Jef*_*ado 15
Count()如您所知,不要使用整个集合必须遍历.
你可以这样做:
public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
return !enumerable.Skip(max).Any();
}
Run Code Online (Sandbox Code Playgroud)
请注意,您仍然需要枚举max集合中的第一个项目,除非您尝试对基础集合做出一些假设,否则这是不可避免的.
要进一步优化这一点,您可以检查基础类型是否为ICollection<>或ICollection访问该Count属性.这样您就不必枚举项目了.否则在枚举项目时回退.
public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
var asCollection = enumerable as System.Collections.ICollection;
if (asCollection != null) return asCollection.Count <= max;
var asGenericCollection = enumerable as ICollection<T>;
if (asGenericCollection != null) return asGenericCollection.Count <= max;
return !enumerable.Skip(max).Any();
}
Run Code Online (Sandbox Code Playgroud)
当然,这并不是完全免费的,因为你正在进行额外的检查,但是如果可能的话,尤其max是在很大的情况下,它必须在集合上进行枚举.
有几种不同的方法可以做到这一点.也许最简单的是:
public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
return enumerable.Take(max+1).Count() <= max;
}
Run Code Online (Sandbox Code Playgroud)