什么是"最佳"(考虑到速度和可读性)的方式来确定列表是否为空?即使列表是类型IEnumerable
且没有Count属性.
现在我在这之间折腾:
if (myList.Count() == 0) { ... }
还有这个:
if (!myList.Any()) { ... }
我的猜测是第二个选项更快,因为它会在看到第一个项目后立即返回结果,而第二个选项(对于IEnumerable)将需要访问每个项目以返回计数.
话虽如此,第二个选项看起来是否可读?你更喜欢哪个?或者你能想出一个更好的方法来测试空列表吗?
编辑 @ lassevk的响应似乎是最合乎逻辑的,再加上一些运行时检查,如果可能的话,使用缓存计数,如下所示:
public static bool IsEmpty(this IEnumerable list) { if (list is ICollection ) return ((ICollection )list).Count == 0; return !list.Any(); }
angry person.. 100
你可以这样做:
public static Boolean IsEmpty(this IEnumerable source) { if (source == null) return true; // or throw an exception return !source.Any(); }
编辑:请注意,如果底层源实际上具有快速Count属性,那么简单地使用.Count方法将会很快.上面的有效优化是检测一些基类型并简单地使用它们的.Count属性,而不是.Any()方法,但如果不能保证,则回退到.Any().
你可以这样做:
public static Boolean IsEmpty(this IEnumerable source) { if (source == null) return true; // or throw an exception return !source.Any(); }
编辑:请注意,如果底层源实际上具有快速Count属性,那么简单地使用.Count方法将会很快.上面的有效优化是检测一些基类型并简单地使用它们的.Count属性,而不是.Any()方法,但如果不能保证,则回退到.Any().
我会对你似乎已经确定的代码做一个小的补充:同时检查ICollection
,因为这甚至是由一些非过时的泛型类(即,Queue
和Stack
)实现的.我也会使用as
而不是is
因为它更惯用,并且已被证明更快.
public static bool IsEmpty(this IEnumerable list) { if (list == null) { throw new ArgumentNullException("list"); } var genericCollection = list as ICollection ; if (genericCollection != null) { return genericCollection.Count == 0; } var nonGenericCollection = list as ICollection; if (nonGenericCollection != null) { return nonGenericCollection.Count == 0; } return !list.Any(); }
LINQ本身必须以某种方式围绕Count()方法进行一些严格的优化.
这让你感到惊讶吗?我想,对于IList
实现,Count
只需直接读取元素的数量,同时Any
必须查询IEnumerable.GetEnumerator
方法,创建实例并MoveNext
至少调用一次.
/编辑@Matt:
我只能假设IEnumerable的Count()扩展方法是这样的:
是的,当然可以.这就是我的意思.实际上,它使用ICollection
而不是IList
结果是相同的.
我刚写了一个快速测试,试试这个:
IEnumerable
第二个差不多慢三倍:)
再次使用堆栈或数组或其他场景尝试秒表测试,它实际上取决于它看起来的列表类型 - 因为它们证明Count更慢.
所以我想这取决于你正在使用的列表类型!
(只是要指出,我在列表中放置了2000多个对象,计数仍然更快,与其他类型相反)