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

时间:2010-06-07 12:11:25

标签: c# linq collections

在最近的一次采访中,我被问到.Any().Length > 0之间的区别是什么,以及为什么我会在测试时使用它来查看集合是否有元素。

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

我建议您在需要知道某个集合包含元素时使用.Length,并在希望过滤结果时使用.Any()

大概.Any()会因为内部循环/查询而受到性能影响。

8 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:12)

我猜测面试官可能打算询问检查Any()Count() > 0(而不是Length > 0)。

基本上,这是交易。

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

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

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

据推测,如果你正在处理一个不起眼的IEnumerable<T>并且你不知道它是否实现了ICollection<T>,那么你使用Any()要好得多。 Count() > 0如果您的目的只是为了确保收集不为空

答案 2 :(得分:1)

Length是数组类型的属性,而Any()Enumerable的扩展方法。因此,只有在使用数组时才能使用Length。使用更抽象的类型(IEnumerable<T>)时,可以使用Any()。

答案 3 :(得分:1)

.Length ... System.Array .Any ... IEnumerable(扩展方法)。

我希望每当我找到它时都会使用“长度”。无论如何,属性比任何方法调用轻。

但是,“Any”的实现不会比下面提到的代码做更多的事情。

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }

另外, 一个更好的问题可能是“.Count”和“.Length”之间的区别,说什么:)。

答案 4 :(得分:0)

我认为如果我们有两种表达方式,这是一个更普遍的问题。 在这种情况下,我会建议声明:Peter Bevig在他的书PAIP中引用“具体”的引用

具体意味着用什么来最好地描述你在做什么。 因此,你想说的是:

collection.isEmpty()

如果你没有这样的结构,我会选择社区使用的常用习语。 对我来说.Length > 0并不是最好的,因为它强加了你可以调整对象的大小。 假设您的工具无限列表。 .Lenght显然不起作用。

答案 5 :(得分:0)

与Stackoverflow问题非常相似,关于.Count和.Any之间的区别,用于检查结果是否存在:Check for Existence of a Result in Linq-to-xml

在这种情况下,最好使用Any然后Count,因为Count将迭代IEnumerable的所有元素

答案 6 :(得分:0)

我们知道.Length仅用于数组,而.Any()用于IEnumerable的集合。

你可以将.Count交换为.Length,你有同样的问题来处理IEnumberable的集合

.Any()和.Count在开始枚举器之前执行空检查。因此,就性能而言,它们是相同的。

至于数组,假设我们有以下行:

int[] foo = new int[10];

这里foo.Length是10.虽然这是正确的,但它可能不是你想要的答案,因为我们尚未向阵列添加任何东西。如果foo为null,则会抛出异常。

答案 7 :(得分:-2)

.Length遍历集合并返回元素数量。复杂性为O(n)

.Any检查集合是否至少有一个项目。复杂性为O(1)