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

C# 访谈问题:.Any()vs if(.Length>;0)用于测试集合是否包含元素,c#,linq,collections,C#,Linq,Collections,在最近的一次采访中,我被问到.Any()和.Length>0之间的区别是什么,以及为什么我在测试集合是否包含元素时会使用这两者 这让我有点吃惊,因为这似乎有点明显,但我觉得我可能遗漏了什么 我建议您在只需要知道集合包含元素时使用.Length,而在希望筛选结果时使用.Any() 大概.Any()也会受到性能影响,因为它必须在内部执行循环/查询。Length仅适用于某些集合类型,例如数组 Any是一种扩展方法,可用于实现IEnumerable的任何集合 如果存在Length,则可以使用它,否则使用

在最近的一次采访中,我被问到
.Any()
.Length>0
之间的区别是什么,以及为什么我在测试集合是否包含元素时会使用这两者

这让我有点吃惊,因为这似乎有点明显,但我觉得我可能遗漏了什么

我建议您在只需要知道集合包含元素时使用
.Length
,而在希望筛选结果时使用
.Any()


大概
.Any()
也会受到性能影响,因为它必须在内部执行循环/查询。

Length
仅适用于某些集合类型,例如
数组

Any
是一种扩展方法,可用于实现
IEnumerable
的任何集合

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


可能.Any()也会受到性能的影响,因为它必须在内部执行循环/查询

可枚举。任何
都不会循环。它获取一个迭代器并检查
MoveNext
是否返回true。这是来自的源代码

公共静态bool Any(此IEnumerable源代码)
{
if(source==null)
{
抛出错误。ArgumentNull(“源”);
}
使用(IEnumerator enumerator=source.GetEnumerator())
{
if(枚举数.MoveNext())
{
返回true;
}
}
返回false;
}

Length
是数组类型的属性,而
Any()
可枚举的扩展方法。因此,只能在使用数组时使用长度。在处理更抽象的类型(
IEnumerable
)时,可以使用Any()。

我认为这是一个更普遍的问题,即如果我们有两种表达方式,应该选择什么。 在这种情况下,我建议使用彼得·诺维格(Peter Norvig)在其著作《和平行动计划》(PAIP)中的“具体”一词

具体的意思是用最好的描述你正在做什么。 因此,你想说的是:

collection.isEmpty()
如果您没有这样的结构,我将选择社区使用的常用习惯用法。 对我来说,
.Length>0
不是最好的,因为它要求您可以调整对象的大小。 假设您的实现是无限列表
.Length
显然不起作用。

.Length。。。系统数组 任何IEnumerable(扩展方法)

只要我能找到,我宁愿使用“长度”。属性无论如何比任何方法调用都要轻

不过,“Any”的实现除了下面提到的代码外,不会做任何事情

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }
private static bool Any(此IEnumerable items)
{
返回项!=null&&items.GetEnumerator().MoveNext();
}
而且,
一个更好的问题可能是“.Count”和“.Length”之间的差异,比如:)。

听起来很像这个关于.Count和.Any之间差异的堆栈溢出问题,用于检查是否存在结果:


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

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

您可以交换.Count for.Length,但在处理IEnumberable集合时会遇到同样的问题

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

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

int[] foo = new int[10];

这里是foo,长度是10。虽然这是正确的,但它可能不是您想要的答案,因为我们尚未向阵列中添加任何内容。如果foo为null,它将抛出一个异常。

我猜面试官可能是想询问检查
Any()
Count()>0
(与
Length>0
相对)

基本上是这样的

Any()
将通过枚举单个项来有效地确定集合是否有任何成员。(使用
Func
检查给定标准时有一个重载,但我猜面试官指的是不带参数的
Any()
版本。)这使得它是O(1)

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

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


大概,如果您正在处理一个不起眼的
IEnumerable
,并且不知道它是否实现了
ICollection
使用
Any()
Count()好得多>0
如果您只是想确保集合不是空的

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


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

还有一个
IQueryable
版本,但我不是OP所说的,可能两者都有。编辑:通过收集我猜你是对的,只是对实体很好奇,
.Count()
是一个选项吗?如果可用,它将使用
.Length
(实际上是
.Count
ICollection
界面),如果不可用,则使用枚举…
。Any()
不可用
int[] foo = new int[10];