在最近的一次采访中,我被问到.Any()
和.Length > 0
之间的区别是什么,以及为什么我会在测试时使用它来查看集合是否有元素。
这让我觉得有点明显,但觉得我可能会遗漏一些东西。
我建议您在需要知道某个集合包含元素时使用.Length
,并在希望过滤结果时使用.Any()
。
大概.Any()
会因为内部循环/查询而受到性能影响。
答案 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()
会首先检查Length
或Count
属性(来自T[]
或ICollection
或ICollection<T>
)。这通常是O(1)。但是,如果它不可用,它将通过枚举整个事物来计算集合中的项目。这将是O(n)。
Count
或Length
属性,如果可用的话,很可能就像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)
。