在最近的一次采访中,我被问到.Any()和.Length > 0之间的区别是什么,以及为什么我在测试一个集合是否有元素时会使用这两种方法。这让我有点吃惊,因为它似乎有点明显,但我觉得我可能错过了一些东西。我建议当你只需要知道一个集合有元素时使用.Length,当你想过滤结果时使用.Any()。大概.Any()也会受到性能的影响,因为它必须在内部执行循环/查询。
.Any()
.Length > 0
.Length
zpgglvta1#
Length只存在于某些集合类型中,例如Array。Any是一个扩展方法,可以用于任何实现IEnumerable<T>的集合。如果存在Length,则可以使用它,否则使用Any。可能.Any()也会受到性能的影响,因为它必须在内部执行循环/查询。Enumerable.Any不会循环。它获取迭代器并检查MoveNext是否返回true。下面是.NET Reflector的源代码。
Length
Array
Any
IEnumerable<T>
Enumerable.Any
MoveNext
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; }
nwnhqdif2#
我猜面试官可能是想问关于检查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 * 属性 *,如果可用的话,很可能是O(1),就像Any()一样,并且可能会表现得更好,因为它根本不需要枚举。但是Count() * 扩展方法 * 并不能确保这一点。因此,它有时是O(1),有时是O(n)。假设你正在处理一个没有描述性的IEnumerable<T>,并且你不知道它是否实现了ICollection<T>,如果你只是想确保集合不是空的,那么你最好使用Any()而不是Count() > 0。
Any()
Count() > 0
Length > 0
Func<T, bool>
Count()
Count
T[]
ICollection
ICollection<T>
iibxawm43#
Length是数组类型的属性,而Any()是Enumerable的扩展方法。因此,只能在处理数组时使用Length。当使用更抽象的类型(IEnumerable<T>)时,可以使用Any()。
Enumerable
fjnneemd4#
.长度...系统.数组.任何... IEnumerable(扩展方法)。我更喜欢用“长度”,只要我能找到它。属性比任何方法调用都要轻量级。不过,“Any”的实现不会做任何事情,除了下面提到的代码。
private static bool Any<T>(this IEnumerable<T> items) { return items!=null && items.GetEnumerator().MoveNext(); }
还有,一个更好的问题本可以是“。计数”和“。长度”的区别,怎么说:)。
k4aesqcs5#
我认为这是一个更普遍的问题,即如果我们有两种表达方式,我们该选择什么。在这种情况下,我建议这样说:“要具体”引用彼得·诺维格在他的书PAIP要具体,就是说用最恰当的方式描述你正在做的事情。所以你想说的是:
collection.isEmpty()
如果你没有这样的结构,我将选择社区使用的常见习语。对我来说,.Length > 0不是最好的,因为它强制你可以调整对象的大小。假设你实现了无限列表。.Lenght显然不起作用。
.Lenght
8yoxcaq76#
听起来很像这个关于.Count和. any之间的差异的Stackoverflow问题,用于检查结果的存在:检查Linq-to-xml中是否存在结果在这种情况下,最好使用Any,然后使用Count,因为Count将迭代IEnumerable的所有元素
uelo1irk7#
我们知道.Length只用于数组,而.Any()用于IEnumerable的集合。您可以将.Count替换为.Length,在处理IEnumberable的集合时也会遇到同样的问题.Any()和.Count都在开始枚举数之前执行空检查。在性能方面,它们是一样的。对于数组,假设我们有以下行:
int[] foo = new int[10];
这里是foo,长度是10。虽然这是正确的,但它可能不是您想要的答案,因为我们还没有向数组中添加任何内容。如果foo为null,则会抛出异常。
xzabzqsa8#
什么是讨论。所有的源代码都是可用的,所以你知道:如果你使用的示例具有Length或Count属性,那么你的时间复杂度总是O(1)。该值是示例的成员,您可以直接与任何其他值进行比较。它只是两个值之间的比较操作。扩展方法Any()总是首先创建一个新的迭代器,并尝试获取第一个元素。它也是O(1),但由于创建了一个新的迭代器,每次调用Any()时都会为这个迭代器分配少量内存。在迭代器使用的MoveNext()的实现中,有2个比较操作和一个基于索引的列表访问,因为MoveNext还保存了成员内部迭代的当前值(参见List的枚举器的实现),这就是为什么如果可以使用,您应该首选使用Count或Length属性。
fafcakar9#
.Length遍历集合并返回元素数。复杂度为O(n).Any检查集合是否至少有一个项。复杂度为O(1)。
O(n)
.Any
O(1)
9条答案
按热度按时间zpgglvta1#
Length
只存在于某些集合类型中,例如Array
。Any
是一个扩展方法,可以用于任何实现IEnumerable<T>
的集合。如果存在
Length
,则可以使用它,否则使用Any
。可能.Any()也会受到性能的影响,因为它必须在内部执行循环/查询。
Enumerable.Any
不会循环。它获取迭代器并检查MoveNext
是否返回true。下面是.NET Reflector的源代码。nwnhqdif2#
我猜面试官可能是想问关于检查
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
* 属性 *,如果可用的话,很可能是O(1),就像Any()
一样,并且可能会表现得更好,因为它根本不需要枚举。但是Count()
* 扩展方法 * 并不能确保这一点。因此,它有时是O(1),有时是O(n)。假设你正在处理一个没有描述性的
IEnumerable<T>
,并且你不知道它是否实现了ICollection<T>
,如果你只是想确保集合不是空的,那么你最好使用Any()
而不是Count() > 0
。iibxawm43#
Length
是数组类型的属性,而Any()
是Enumerable
的扩展方法。因此,只能在处理数组时使用Length。当使用更抽象的类型(IEnumerable<T>
)时,可以使用Any()。fjnneemd4#
.长度...系统.数组.任何... IEnumerable(扩展方法)。
我更喜欢用“长度”,只要我能找到它。属性比任何方法调用都要轻量级。
不过,“Any”的实现不会做任何事情,除了下面提到的代码。
还有,一个更好的问题本可以是“。计数”和“。长度”的区别,怎么说:)。
k4aesqcs5#
我认为这是一个更普遍的问题,即如果我们有两种表达方式,我们该选择什么。在这种情况下,我建议这样说:“要具体”引用彼得·诺维格在他的书PAIP
要具体,就是说用最恰当的方式描述你正在做的事情。所以你想说的是:
如果你没有这样的结构,我将选择社区使用的常见习语。对我来说,
.Length > 0
不是最好的,因为它强制你可以调整对象的大小。假设你实现了无限列表。.Lenght
显然不起作用。8yoxcaq76#
听起来很像这个关于.Count和. any之间的差异的Stackoverflow问题,用于检查结果的存在:检查Linq-to-xml中是否存在结果
在这种情况下,最好使用Any,然后使用Count,因为Count将迭代IEnumerable的所有元素
uelo1irk7#
我们知道.Length只用于数组,而.Any()用于IEnumerable的集合。
您可以将.Count替换为.Length,在处理IEnumberable的集合时也会遇到同样的问题
.Any()和.Count都在开始枚举数之前执行空检查。在性能方面,它们是一样的。
对于数组,假设我们有以下行:
这里是foo,长度是10。虽然这是正确的,但它可能不是您想要的答案,因为我们还没有向数组中添加任何内容。如果foo为null,则会抛出异常。
xzabzqsa8#
什么是讨论。所有的源代码都是可用的,所以你知道:如果你使用的示例具有Length或Count属性,那么你的时间复杂度总是O(1)。该值是示例的成员,您可以直接与任何其他值进行比较。它只是两个值之间的比较操作。
扩展方法Any()总是首先创建一个新的迭代器,并尝试获取第一个元素。它也是O(1),但由于创建了一个新的迭代器,每次调用Any()时都会为这个迭代器分配少量内存。在迭代器使用的MoveNext()的实现中,有2个比较操作和一个基于索引的列表访问,因为MoveNext还保存了成员内部迭代的当前值(参见List的枚举器的实现),这就是为什么如果可以使用,您应该首选使用Count或Length属性。
fafcakar9#
.Length
遍历集合并返回元素数。复杂度为O(n)
.Any
检查集合是否至少有一个项。复杂度为O(1)
。