如何检查IEnumerable是空还是空?

Sch*_*999 144 .net c# linq collections ienumerable

我爱string.IsNullOrEmpty方法.我很想拥有能够为IEnumerable提供相同功能的东西.有这样的吗?也许一些收集助手班?我问的原因是,在if语句中,如果模式是代码,代码看起来很混乱(mylist != null && mylist.Any()).拥有它会更加清洁Foo.IsAny(myList).

这篇文章没有给出答案:IEnumerable是空的?.

Mar*_*ell 176

当然你可以这样写:

public static class Utils {
    public static bool IsAny<T>(this IEnumerable<T> data) {
        return data != null && data.Any();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,要小心并非所有序列都是可重复的; 一般来说,我宁愿只走一次,以防万一.

  • @Mormegil为什么?扩展方法最终赋予C#一些使用null的能力,其他语言(如Ruby)完全认为是理所当然的. (28认同)
  • 这是一个好模式吗?我会把`this`放在那里 - 我认为扩展方法被认为是在`null`上调用,作为丑陋设计的标志. (11认同)
  • 为什么这个_必然不好?在这种情况下,它有时非常方便,因为它可以让您更均匀地处理事物,并减少特殊情况. (5认同)
  • @Mormegil meh - 我不能为此感到兴奋.只要意图明确,等等 (5认同)
  • @Miryafa` .Any()`是一个扩展方法,它运行在`IEnumerable <T>`(或`IQueryable <T>`,尽管这是一个不同的场景).这样做**消耗序列**,至少部分消耗(虽然这仍然意味着它被消耗) - 它可能只需要读取一个元素(特别是如果没有谓词).因此,因为序列(`IEnumerable <T>`)不需要是可重复的,**可能是**.没有谓词的`Any()`*基本上*等同于`foreach(var x in sequence){return true; 返回false;` - 虽然它使用`GetEnumerator()`等而不是编译器语法 (5认同)
  • 我认为它没有任何问题,只要没有暗示它不应该是空的. (2认同)
  • 即使 C++ 也允许 `this` 为 `null`。您可以在空对象上调用非虚拟函数,我过去实际上发现这很有用一两次。 (2认同)
  • 你能否澄清一下:"并非所有的序列都是可重复的;通常我更喜欢只走一次"?调用data.Any()与序列有什么关系? (2认同)
  • @MarcGravell明白了-谢谢!换句话说,某些序列在遍历时会更改,而Any()遍历该序列。 (2认同)

Mat*_*eer 117

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) {
    return enumerable == null || !enumerable.Any();
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,不完全,OP要求IEnumerable,而不是IEnumerable <T> ;-) (7认同)
  • 是的,`IEnumerable`没有`Any()`扩展名. (7认同)

yoy*_*oyo 21

这是@Matt Greer的有用答案的修改版本,其中包含一个静态包装类,因此您可以将其复制粘贴到新的源文件中,不依赖于Linq,并添加泛型IEnumerable<T>重载,以避免值类型的装箱非通用版本会发生这种情况.[编辑:请注意,使用IEnumerable<T>不会阻止枚举器的装箱,鸭子打字无法阻止,但至少在值类型集合中的元素不会被装箱.]

using System.Collections;
using System.Collections.Generic;

public static class IsNullOrEmptyExtension
{
    public static bool IsNullOrEmpty(this IEnumerable source)
    {
        if (source != null)
        {
            foreach (object obj in source)
            {
                return false;
            }
        }
        return true;
    }

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        if (source != null)
        {
            foreach (T obj in source)
            {
                return false;
            }
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*ren 15

另一种方法是获取Enumerator并调用MoveNext()方法以查看是否有任何项:

if (mylist != null && mylist.GetEnumerator().MoveNext())
{
    // The list is not null or empty
}
Run Code Online (Sandbox Code Playgroud)

这适用于IEnumerable以及IEnumerable <T>.

  • 你应该给这个调查员打电话吗?如果集合是多线程知道的?是.http://stackoverflow.com/questions/13459447/do-i-need-to-consider-disposing-of-any-ienumerablet-i-use (4认同)
  • @TamusJRoyce注意,您的声明仅对“ IEnumerable &lt;T&gt;”有效,因为非通用的“ IEnumerable”不实现“ IDisposable”。 (2认同)

小智 6

我这样做,利用一些现代的C#功能:

选项1)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any() ?? false);
    }
}
Run Code Online (Sandbox Code Playgroud)

选项2)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any()).GetValueOrDefault();
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,永远不要使用Count == 0Count() == 0只是检查一个集合是否为空.总是使用Linq的.Any()

  • 计数== 0就好了......也许比Any()更快?但是你在Count()== 0是坏的时候是正确的.对于那些想知道Count()遍历整个集合的人来说,如果它庞大可能会增加大量的开销! (2认同)

Sch*_*ltz 6

if (collection?.Any() == true){
    // if collection contains more than one item
}
if (collection?.Any() != true){
    // if collection is null
    // if collection does not contain any item
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*der 5

从C#6开始,您可以使用null传播myList?.Any() == true

如果您仍然觉得这个问题过于冗长或不喜欢使用一种很好的扩展方法,我会推荐Matt Greer和Marc Gravell的答案,但其中有些扩展功能可以确保完整性。

他们的答案提供了相同的基本功能,但每个答案都是从另一个角度出发的。马特(Matt)的答案使用string.IsNullOrEmpty-mentality,而马克(Marc)的答案则采用Linq的方式.Any()完成工作。

我个人倾向于使用这.Any()条路,但想从该方法的其他重载中添加条件检查功能:

    public static bool AnyNotNull<T>(this IEnumerable<T> source, Func<T, bool> predicate = null)
    {
        if (source == null) return false;
        return predicate == null
            ? source.Any()
            : source.Any(predicate);
    }
Run Code Online (Sandbox Code Playgroud)

因此,您仍然可以执行以下操作: myList.AnyNotNull(item=>item.AnswerToLife == 42);与常规操作一样,.Any()但添加了null检查

请注意,使用C#6方法:myList?.Any()返回a bool?而不是a bool,这是传播 null 的实际效果


Hos*_*Rad 5

这可能会有所帮助

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

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
    return enumerable?.Any() != true;
}
Run Code Online (Sandbox Code Playgroud)


Moh*_*reh 5

当涉及引用(可为空)类型并且项目中不存在空项目时,可以使用这一行进行验证

myCollection?.FirstOrDefault() == null
Run Code Online (Sandbox Code Playgroud)