方法返回一个序列IEnumerable<T>
,您现在想要检查它是否为空。你怎么建议这样做?我正在寻找良好的可读性和良好的性能。
第一种也是最明显的方法是检查计数是否大于零:
if(sequence.Count() == 0)
具有良好的可读性,但性能很差,因为它必须实际完成整个序列。
我有时使用的方法如下:
if(!sequence.Any())
这不(据我所知)必须经历整个序列,但可读性有点倒退和尴尬。 (如果我们检查序列不为空,则读得更好。)
另一个选择是在try-catch中使用First
,如下所示:
try
{
sequence.First();
}
catch(InvalidOperationException)
{
// Do something
}
不是一个非常漂亮的解决方案,也可能更慢,因为它使用异常和东西。当然可以使用FirstOrDefault
来阻止这种情况,但如果序列中的第一项 是的默认值,则会出现大问题;)
那么,检查序列是否为空的任何其他方法?你经常使用哪一个?你建议使用哪一个?
注意: 为了获得最佳的可读性,我可能会将上述代码段中的一个放在IsEmpty
扩展方法中,但我仍然很好奇,因为我也必须在该方法中做一些事情:p
答案 0 :(得分:81)
我会亲自使用!sequence.Any()
。
如果确实需要,您可以随时编写自己的扩展方法:
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
return !source.Any();
}
然后你可以写:
if (sequence.IsEmpty())
答案 1 :(得分:5)
您可以使用此实现创建Extension方法。
public static bool IsEmpty<T>(this IEnumerable<T> items) {
using (var enumerator = items.GetEnumerator())
{
return !enumerator.MoveNext();
}
}
答案 2 :(得分:2)
您调用的所有这些方法都是LINQ扩展方法,因此它取决于LINQ提供程序的实现方式。如果您想知道序列是否为空,则Count() == 0
或Any() == false
是合适的。我自己更喜欢Any()
。
但是,根据您的sequence
的实际类型,您可能不需要使用LINQ扩展方法。即如果它是一个数组,你可以调用sequence.Length
。如果它是一个集合,您可以使用sequence.Count
。
答案 3 :(得分:0)
你说:
if(sequence.Count() == 0)
具有良好的可读性,但性能可怕,因为它必须实际完成整个序列。
这是真的吗?您正在讨论处理接口,IEnumerable<T>
,但您正在对其实现进行假设,这可能是也可能不是。事实上,我多年来编写的许多自定义集合都保留了一个私有变量,用于在内部存储当前计数,这意味着返回.Count
是一件微不足道的事情,不需要迭代整个集合。
因此,除非您知道某个特定实现针对.Count
进行了优化,否则我会使用.Count
。尽可能避免过早优化,并坚持可读性。
答案 4 :(得分:0)
我有时使用的方法如下:
b.h
❶这不(据我所知)必须经历整个序列, ❷但可读性有点倒退和尴尬。 (读了很多 如果我们检查序列不是空的,那就更好了。
结果可以立即停止
if(!sequence.Any())
的枚举 确定。
在测试source
语句中是否存在元素时尤其如此。可以说,如果检测if-else
语句中元素的存在以及if
中缺少元素,那么可读性最好,从而避免使用else
运算符:
!
大多数人会认为比以下更具可读性
if (sequence.Any())
{
}
else
{
}
答案 5 :(得分:-1)
我使用此扩展方法来检测序列是否为空或者没有任何项目,或者检测序列是否至少有一个项目,就像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...
}