面试问题:.Any()vs if(.Length> 0)用于测试集合是否包含元素

Chr*_*ris 18 c# linq collections

在最近的采访中,我问有什么区别.Any().Length > 0过去是,为什么我会请使用测试,看是否有收集了元素时.

这让我觉得有点明显,但觉得我可能会遗漏一些东西.

我建议您.Length在只需要知道集合中包含元素以及.Any()何时希望过滤结果时使用.

.Any()由于必须在内部执行循环/查询,因此可能会受到性能影响.

Mar*_*ers 24

Length仅适用于某些集合类型,例如Array.

Any是一种扩展方法,可以与任何实现的集合一起使用IEnumerable<T>.

如果Length存在则可以使用它,否则使用Any.


据推测.Any()因为必须在内部进行循环/查询而受到性能影响.

Enumerable.Any不循环.它获取一个迭代器并检查是否MoveNext返回true.这是.NET Reflector的源代码.

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*Tao 13

我猜测面试官可能打算询问检查Any()Count() > 0(相反Length > 0).

基本上,这是交易.

Any()将有效地尝试通过枚举单个项目来确定集合是否具有任何成员.(使用a检查给定标准有一个超载Func<T, bool>,但我猜测采访者指的Any()是没有参数的版本.)这使得它成为O(1).

Count()将检查LengthCount属性(从一个T[]或一个ICollectionICollection<T>)第一个.这通常是O(1).但是,如果它不可用,它将通过枚举整个事物来计算集合中的项目.这将是O(n).

A CountLength 属性(如果可用)很可能是O(1)Any(),并且可能会表现得更好,因为它根本不需要枚举.但是Count() 扩展方法并不能确保这一点.因此它有时是O(1),有时是O(n).

据推测,如果你正在处理一个不伦不类的IEnumerable<T>,你不知道它是否实现ICollection<T>与否,你都好得多使用Any()Count() > 0如果你的意图仅仅是为了确保集合不为空.