C# 检查序列是否为空的推荐方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2094729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Recommended way to check if a sequence is empty
提问by Svish
A method returns a sequence, IEnumerable<T>
, and you now want to check if it is empty. How do you recommend doing that? I'm looking for both good readability and good performance.
一个方法返回一个序列,IEnumerable<T>
,您现在想要检查它是否为空。你怎么建议这样做?我正在寻找良好的可读性和良好的性能。
The first and most obvious way is to check that the count is greater than zero:
第一个也是最明显的方法是检查计数是否大于零:
if(sequence.Count() == 0)
Has decent readability, but terrible performance since it has to actually go through the whole sequence.
具有不错的可读性,但性能很差,因为它必须实际遍历整个序列。
A method that I sometimes use is the following:
我有时使用的方法如下:
if(!sequence.Any())
This doesn't (as far as I know) have to go through the whole sequence, but the readability is a bit backwards and awkward. (Reads a lot better if we are checking that the sequence is notempty though).
这(据我所知)不必遍历整个序列,但可读性有点倒退和尴尬。(如果我们检查序列不是空的,读起来会好得多)。
Another option is to use First
in a try-catch, like this:
另一种选择是First
在 try-catch 中使用,如下所示:
try
{
sequence.First();
}
catch(InvalidOperationException)
{
// Do something
}
Not a very pretty solution, and probably slower too, since it is using exceptions and stuff. Could prevent that by using FirstOrDefault
of course, except you would have a big problem if the first item in the sequence actually wasthe default value ;)
不是一个非常漂亮的解决方案,而且可能更慢,因为它使用了异常和东西。FirstOrDefault
当然可以通过使用来防止这种情况,除非如果序列中的第一项实际上是默认值,那么您会遇到大问题;)
So, any other ways to check if a sequence is empty? Which one do you usually use? Which one do you recommend to use?
那么,还有其他方法可以检查序列是否为空吗?你通常使用哪一种?您推荐使用哪一种?
Note:For optimal readability I would probably put one of the above snippets in an IsEmpty
extension method, but I am still curious since I would have to do something inside that method as well :p
注意:为了获得最佳可读性,我可能会将上述片段之一放在IsEmpty
扩展方法中,但我仍然很好奇,因为我也必须在该方法中做一些事情:p
采纳答案by Jon Skeet
I would use !sequence.Any()
, personally.
我!sequence.Any()
个人会用。
If you reallyneed to, you could always write your own extension method:
如果你真的需要,你总是可以编写自己的扩展方法:
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
return !source.Any();
}
Then you can write:
然后你可以写:
if (sequence.IsEmpty())
回答by Neil Barnwell
Well all these methods you're calling are LINQ extension methods, so it depends how the LINQ provider was implemented. If you want to know if a sequence is empty, either Count() == 0
or Any() == false
is appropriate. I prefer Any()
myself.
好吧,您调用的所有这些方法都是 LINQ 扩展方法,因此这取决于 LINQ 提供程序的实现方式。如果你想知道,如果一个序列是空的,要么Count() == 0
或者Any() == false
是适当的。我更喜欢Any()
我自己。
However, depending on what actual Type your sequence
is, you might not need to use a LINQ extension method. I.e. if it's an array you can call sequence.Length
. If it's a collection, you can use sequence.Count
.
但是,根据您的实际类型sequence
,您可能不需要使用 LINQ 扩展方法。即,如果它是一个数组,您可以调用sequence.Length
. 如果它是一个集合,则可以使用sequence.Count
.
回答by Manish Basantani
You can create an Extension method, with this implementation.
您可以使用此实现创建扩展方法。
public static bool IsEmpty<T>(this IEnumerable<T> items) {
using (var enumerator = items.GetEnumerator())
{
return !enumerator.MoveNext();
}
}
回答by Nick
You said:
你说:
if(sequence.Count() == 0)
Has decent readability, but terrible performance since it has to actually go through the whole sequence.
if(sequence.Count() == 0)
具有不错的可读性,但性能很差,因为它必须实际遍历整个序列。
Is that actually true? You are talking about dealing with an Interface, IEnumerable<T>
, and yet you are making assumptions regarding its implementation which may or may not be true. In fact, many of the custom collections I've written over the years keep a private variable that stores the current count internally, which means that returning .Count
is a trivial matter that does not require iterating the entire collection.
这是真的吗?您正在谈论处理Interface, IEnumerable<T>
,但您正在对其实现做出假设,这可能是也可能不是。事实上,我多年来编写的许多自定义集合都保留了一个私有变量,用于在内部存储当前计数,这意味着返回.Count
是一件小事,不需要迭代整个集合。
So with that said, unless you know that a specific implementation is poorly optimized for .Count
, I would use .Count
. Avoid premature optimization wherever possible, and stick with readability.
因此,随着中说,除非你知道一个具体实现优化不好.Count
,我会用.Count
。尽可能避免过早优化,并坚持可读性。
回答by Sagi
I use this extension methods to detect if the sequence is null or does not have any item and alternatively to detect if the sequence does have at least one item, much like the string.IsNullOrEmpty()
method.
我使用这个扩展方法来检测序列是否为空或没有任何项目,或者检测序列是否至少有一个项目,就像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...
}
回答by DavidRR
A method that I sometimes use is the following:
if(!sequence.Any())
❶This doesn't (as far as I know) have to go through the whole sequence, ❷but the readability is a bit backwards and awkward. (Reads a lot better if we are checking that the sequence is not empty though).
我有时使用的方法如下:
if(!sequence.Any())
❶这(据我所知)不必遍历整个序列, ❷但可读性有点倒退和尴尬。(如果我们检查序列不是空的,读起来会好得多)。
- According to Microsoft, Anydoes indeed nothave to go through the whole sequence. Quoting from the section Remarks:
- 根据微软的说法,Any确实不必经历整个序列。引用部分备注:
The enumeration of
source
is stopped as soon as the result can be determined.
source
一旦可以确定结果,就停止枚举。
This is particularly true when testing for the presence of elements in an
if-else
statement. Arguably, readability is best if one tests for the presence of elements in theif
statement, and the absence of elements in theelse
, thereby avoiding the use of the!
operator:if (sequence.Any()) { } else { }
Most would consider that more readable than:
if (!sequence.Any()) { } else { }
在测试
if-else
语句中是否存在元素时尤其如此。可以说,如果测试if
语句中元素的存在和 中元素的缺失,那么可读性是最好的else
,从而避免使用!
运算符:if (sequence.Any()) { } else { }
大多数人会认为比以下内容更具可读性:
if (!sequence.Any()) { } else { }