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];