C#是否具有List/IEnumerable的IsNullOrEmpty?

Eri*_*Yin 66 c# ienumerable isnullorempty

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

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

对于字符串,我们有IsNullOrEmpty.有没有C#本身为List或IEnumerable做同样的事情?

Mat*_*nes 68

没有任何东西融入框架,但它是一个非常直接的扩展方法.

看这里

/// <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(); 
    }
Run Code Online (Sandbox Code Playgroud)

出于性能原因,Daniel Vaughan采取额外的步骤进行ICollection(尽可能).我不会想到的东西.

  • 如下所示:http://msdn.microsoft.com/en-us/library/bb337697%28v=vs.110%29.aspx(check remarks)"只要结果可以确定,就会停止源的枚举".因为enumerable.Any()也应该有O(1),所以我认为转换为集合是不必要的.如果你真的不知道它是一个列表,为什么要列入一个列表呢? (7认同)
  • 必须注意,对`enumerable.Any()`的调用可能会丢失不可重绕的枚举元素.你可以把它包装成能够跟踪第一个元素的东西(并且当然很好地处理null或者我们否定OP的整个问题),但是在某些情况下可以更方便地与空枚举合并并只使用结果. (5认同)
  • 现在可以用一行写出:return a == null || ((作为ICollection)?. Count == 0)|| !a.Any(); (3认同)
  • @ElMac ICollection.Count的规范是对计数进行跟踪,任何实现都应返回该计数,而无需迭代值以根据需要进行计算。但是正如另一个人在评论中所说,也应该为IReadOnlyCollection调用相同的优化。另外,LINQ.Any在ICollection上使用优化,但不在IReadOnlyCollection上使用。 (2认同)

Teo*_*ite 40

延迟更新:从C#6.0开始,null-propagation运算符可用于表达简洁如下:

if (  list?.Count  > 0 ) // For List<T>
if ( array?.Length > 0 ) // For Array<T>
Run Code Online (Sandbox Code Playgroud)

注1: IEnumerable<T>是必要的,因为以下原因(摘要/引自本文):

IsNotNullOrEmptyIsNullOrEmpty如果是儿童成员,则操作员将返回if (!(list?.Count > 0)).但是如果我们试图得到一个非?? false成员,比如 ?.返回null[...]的方法,那么编译器将"包装"一个返回值null.例如,Nullable将给我们Any()(这是bool),而不是Nullable<>.[...]因为它无法隐式地转换Object?.Any()为此表达式所以无法使用bool?

注2:作为奖励,该声明也是"线程安全的"(引用该问题的答案):

在多线程上下文中,如果[ enumerable ]可以从另一个线程访问(因为它是一个可访问的字段,或者因为它在暴露给另一个线程的lambda中被关闭),那么每次计算时该值都可能不同[ ieprior null - 检查 ]


Ode*_*ded 24

内置任何东西.

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

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

  return !enumerable.Any();
}
Run Code Online (Sandbox Code Playgroud)


Jus*_*ner 9

var nullOrEmpty = list == null || !list.Any();
Run Code Online (Sandbox Code Playgroud)