推荐的方法来检查一个序列是否为空

一个方法返回一个序列, IEnumerable<T> ,现在你想检查它是否为空。 你如何推荐这样做? 我正在寻找良好的可读性和良好的性能。

第一个也是最明显的方法是检查计数是否大于零:

 if(sequence.Count() == 0) 

有可观的可读性,但可怕的performance,因为它必须实际上贯穿整个序列。

我有时使用的方法如下:

 if(!sequence.Any()) 

这不(据我所知)必须经历整个序列,但可读性有点落后和尴尬。 (如果我们检查序列不是空的,则读取更好)。

另一个select是在尝试捕获中使用First ,如下所示:

 try { sequence.First(); } catch(InvalidOperationException) { // Do something } 

不是一个非常漂亮的解决scheme,也可能更慢,因为它使用exception和东西。 当然可以通过使用FirstOrDefault来防止,除非序列中的第一个项目实际上默认值,否则会有很大的问题;)

那么,还有其他的方法来检查序列是否为空? 你通常使用哪一个? 你推荐使用哪一个?

注意:为了获得最佳的可读性,我可能会把上面的代码片段放到一个IsEmpty扩展方法中,但是我还是很好奇,因为我也不得不在这个方法中做一些事情:p

我会使用!sequence.Any() ,亲自。

如果你真的需要,你可以随时写自己的扩展方法:

 public static bool IsEmpty<T>(this IEnumerable<T> source) { return !source.Any(); } 

那么你可以写:

 if (sequence.IsEmpty()) 

您可以使用此实现创build一个扩展方法。

 public static bool IsEmpty<T>(this IEnumerable<T> items) { using (var enumerator = items.GetEnumerator()) { return !enumerator.MoveNext(); } } 

那么你调用的所有这些方法都是LINQ扩展方法,所以这取决于LINQ提供程序是如何实现的。 如果您想知道序列是否为空,则Count() == 0Any() == false是适当的。 我更喜欢Any()我自己。

但是,根据您的sequence实际types,您可能不需要使用LINQ扩展方法。 也就是说,如果它是一个数组,你可以调用sequence.Length 。 如果它是一个集合,你可以使用sequence.Count

你说:

if(sequence.Count() == 0)具有可观的可读性,但是由于它必须实际经历整个序列,所以性能很差。

这是真的吗? 你正在谈论处理一个接口IEnumerable<T> ,然而你正在做它的实现,可能会或可能不会是真实的假设。 实际上,这些年来我写的许多自定义集合都保留了一个私有variables,它在内部存储当前的计数,这意味着返回.Count是一件微不足道的事情,不需要迭代整个集合。

所以说,除非你知道一个具体的实现是很差的.Count优化,我会使用.Count 。 尽可能避免过早优化,并坚持可读性。

我使用这个扩展方法来检测序列是否为空或没有任何项目,或者检测序列是否至less有一个项目,就像string.IsNullOrEmpty()方法一样。

  public static bool IsNullOrEmpty<TSource>(this IEnumerable<TSource> source) { if (source == null) { return true; } return !source.Any(); } public static bool IsNotNullOrEmpty<TSource>(this IEnumerable<TSource> source) { return !source.IsNullOrEmpty(); } . . . if (!sequence.IsNullOrEmpty()) { //Do Something with the sequence... }