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

时间:2011-12-20 21:41:30

标签: c# ienumerable isnullorempty

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

  1. 我必须明确检查和处理空值,避免错误和攻击。
  2. 之后很容易执行??操作以获得返回值。
  3. 对于字符串,我们有IsNullOrEmpty。有什么来自C#本身为List或IEnumerable做同样的事情吗?

10 个答案:

答案 0 :(得分:65)

没有任何内容融入到框架中,但它是一种非常简单的扩展方法。

See here

/// <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(如果可能)。我不会想到的东西。

答案 1 :(得分:36)

延迟更新:自C#6.0起, null-propagation运算符可用于表达简洁:

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

注1: ?? false是必要的,原因如下(摘要/来自this post的引用):

  如果子成员为?.

null运算符将返回null。   但是如果我们试图获得一个非Nullable成员,就像   Any()方法,返回编译器将bool [...]   “包裹”Nullable<>中的返回值。例如,Object?.Any()会   给我们bool?Nullable<bool>),而不是bool。   [...]由于无法隐式投放到bool,因此if无法使用此表达式

注2:作为奖励,该声明也是“线程安全的”(引自this question的答案):

  

在多线程上下文中,如果可以从另一个访问[枚举]   线程(因为它是一个可访问的字段或因为它是   在暴露于另一个线程的lambda中关闭)然后是   每次计算[ ieprior null-check ]

时,值可能会有所不同

答案 2 :(得分:24)

内置任何东西。

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

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

  return !enumerable.Any();
}

答案 3 :(得分:9)

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

答案 4 :(得分:1)

如果您需要能够在不是空的情况下检索所有元素,那么这里的一些答案将无法正常工作,因为对非Any()的调用可以回收的数字会忘记&#34;忘记&#34;一个元素。

您可以采取不同的方法并将空值转换为空白:

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()等。

答案 5 :(得分:1)

正如其他人所说,框架中没有任何内容,但如果您使用的是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;
            }
            ...

答案 6 :(得分:1)

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

$TestMax = 10 #test 1000 times
$SleepMS = 1000 #wait 1 second between each test to allow the feeding match a headstart on the matches
$Evens = 1..(2*$TestMax) | %{
    "$_"
} | ?{
    $_ -match '^(?<EvenNumber>.*[02468])$'
} | <#sort | #> %{
    Start-Sleep -Milliseconds $SleepMS
    $matches.EvenNumber
}
$ExpectedResult = 1..$TestMax  | %{"$($_*2)"}
if ((Compare-Object -ReferenceObject $Evens -DifferenceObject $ExpectedResult -SyncWindow 0) -eq $null) {
    ":)"
} else {
    ":("
}

答案 7 :(得分:0)

我修改了Matthew Vines的建议,以避免&#34;可能多次枚举IEnumerable&#34; - 问题。 (另见Jon Hanna的评论)

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

......和单元测试:

[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());
}

答案 8 :(得分:0)

对我来说最好的isNullOrEmpty方法看起来像这样

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

答案 9 :(得分:-1)

var nullOrEmpty = !( list?.Count > 0 );