C#对于List / IEnumerable是否有IsNullOrEmpty?

我知道一般空列表比NULL更喜欢。 但是我将返回NULL,主要有两个原因

  1. 我必须明确地检查和处理空值,以避免错误和攻击。
  2. 这很容易执行?? 之后的操作来获得返回值。

对于string,我们有IsNullOrEmpty。 有没有什么从C#本身做List或IEnumerable同样的事情?

没有东西被纳入框架,但它是一个非常直接的扩展方法。

看这里

 /// <summary> /// Determines whether the collection is null or contains no elements. /// </summary> /// <typeparam name="T">The IEnumerable type.</typeparam> /// <param name="enumerable">The enumerable, which may be null or empty.</param> /// <returns> /// <c>true</c> if the IEnumerable is null or empty; otherwise, <c>false</c>. /// </returns> public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { if (enumerable == null) { return true; } /* If this is a list, use the Count property for efficiency. * The Count property is O(1) while IEnumerable.Count() is O(N). */ var collection = enumerable as ICollection<T>; if (collection != null) { return collection.Count < 1; } return !enumerable.Any(); } 

由于性能的原因,Daniel Vaughan采取了额外的步骤将其投射到ICollection(在可能的情况下)。 一些我不会想到的事情。

没有内置任何东西。

这是一个简单的扩展方法:

 public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) { if(enumerable == null) return true; return !enumerable.Any(); } 

后期更新 :自C#6.0以来,可以使用空传播操作符来表示简洁,如下所示:

 if (enumerable?.Any() ?? false) 

注1: ?? false ?? false是必要的,因为以下原因(摘要/引自本文 ):

?. 如果子成员为null则运算符将返回null 。 但是,如果我们尝试获取非Nullable成员,如Any()方法,则返回bool […],编译器将用Nullable<>包装返回值。 例如, Object?.Any()会给我们bool? (可为Nullable<bool> ),而不是bool 。 […]因为它不能被隐式地转换成bool这个expression式不能用在if

注2:作为奖励,声明也是“线程安全的”(引自这个问题的答案):

在multithreading上下文中,如果[ enumerable ]可以从另一个线程访问(或者是因为它是一个可访问的字段,或者是因为它在暴露给另一个线程的lambda中closures了),那么每次计算它的值就可能不同[ ieprior null – 检查 ]

 var nullOrEmpty = list == null || !list.Any(); 

如果您需要在不为空的情况下检索所有元素,那么这里的某些答案将不起作用,因为对不可回退的enumerable调用Any()会“忘记”一个元件。

你可以采取不同的方法,将空值转换为空值:

 bool didSomething = false; foreach(var element in someEnumeration ?? Enumerable.Empty<MyType>()) { //some sensible thing to do on element... didSomething = true; } if(!didSomething) { //handle the fact that it was null or empty (without caring which). } 

同样(someEnumeration ?? Enumerable.Empty<MyType>()).ToList()等可以使用。

正如其他人所说,框架没有内置任何东西,但如果你使用的是Castle,那么Castle.Core.Internal就是这样。

 using Castle.Core.Internal; namespace PhoneNumbers { public class PhoneNumberService : IPhoneNumberService { public void ConsolidateNumbers(Account accountRequest) { if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T> { return; } ... 

我修改了Matthew Vines的build议,以避免“IEnumerable的可能的多个枚举” – 问题。 (另见Jon Hanna的评论)

 public static bool IsNullOrEmpty(this IEnumerable items) => items == null || (items as ICollection)?.Count == 0 || !items.GetEnumerator().MoveNext(); 

…和unit testing:

 [Test] public void TestEnumerableEx() { List<int> list = null; Assert.IsTrue(list.IsNullOrEmpty()); list = new List<int>(); Assert.IsTrue(list.IsNullOrEmpty()); list.AddRange(new []{1, 2, 3}); Assert.IsFalse(list.IsNullOrEmpty()); var enumerator = list.GetEnumerator(); for(var i = 1; i <= list.Count; i++) { Assert.IsFalse(list.IsNullOrEmpty()); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(i, enumerator.Current); } Assert.IsFalse(list.IsNullOrEmpty()); Assert.IsFalse(enumerator.MoveNext()); } 
 var nullOrEmpty = !( list?.Count > 0 ); 

把以前的答案放到C#6.0+的简单扩展方法中:

  public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;