我喜欢绳子。IsNullOrEmpty方法。我想有一些东西,将允许相同的功能IEnumerable。有这样的东西吗?也许是一些收集助手类?我问的原因是,在if语句中,如果模式是(mylist != null && mylist. any()),代码看起来很混乱。使用Foo.IsAny(myList)会干净得多。

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


当前回答

这可能会有所帮助

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;
}

其他回答

从c# 6开始,你可以使用空传播:myList?.Any() == true

如果你仍然觉得这个方法太麻烦或者更喜欢一个好的扩展方法,我会推荐Matt Greer和Marc Gravell的答案,但为了完整性,还需要一些扩展功能。

他们的答案提供了相同的基本功能,但各从不同的角度。Matt的答案使用了字符串。isnullorempty心态,而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);
    }

所以你仍然可以做这样的事情: myList.AnyNotNull(项= >项目。AnswerToLife == 42);就像使用常规的.Any()一样,但添加了空检查

注意,使用c# 6的方式:myList?.Any()返回bool?而不是bool类型,这是传播null的实际效果

我根据@Matt Greer的回答构建了这个

他完美地回答了那位警官的问题。

我想要这样的东西,同时保持Any的原始功能,同时还检查null。我张贴这个以防其他人需要类似的东西。

具体来说,我希望仍然能够传递一个谓词。

public static class Utilities
{
    /// <summary>
    /// Determines whether a sequence has a value and contains any elements.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">The <see cref="System.Collections.Generic.IEnumerable"/> to check for emptiness.</param>
    /// <returns>true if the source sequence is not null and contains any elements; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source)
    {
        return source?.Any() == true;
    }

    /// <summary>
    /// Determines whether a sequence has a value and any element of a sequence satisfies a condition.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">An <see cref="System.Collections.Generic.IEnumerable"/> whose elements to apply the predicate to.</param>
    /// <param name="predicate">A function to test each element for a condition.</param>
    /// <returns>true if the source sequence is not null and any elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        return source?.Any(predicate) == true;
    }
}

扩展方法的命名可能会更好。

这可能会有所帮助

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;
}

由于一些资源在一次读取后会耗尽,我想为什么不将检查和读取结合起来,而不是传统的单独检查,然后读取。

首先,我们有一个更简单的检查为空的内联扩展:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNull<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null) => source ?? throw new System.ArgumentNullException(paramName ?? nameof(source));

var first = source.ThrowOnNull().First();

然后我们有一些更复杂的(好吧,至少我写它的方式)检查为空和空的内联扩展:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNullOrEmpty<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null)
{
  using (var e = source.ThrowOnNull(paramName).GetEnumerator())
  {
    if (!e.MoveNext())
    {
      throw new System.ArgumentException(@"The sequence is empty.", paramName ?? nameof(source));
    }

    do
    {
      yield return e.Current;
    }
    while (e.MoveNext());
  }
}

var first = source.ThrowOnNullOrEmpty().First();

当然,您仍然可以在不继续调用链的情况下调用两者。此外,我还包含了paramName,以便调用者可以为错误包含一个替代名称,如果它不是“源”被检查,例如。“nameof(目标)”。

我的做法是,利用一些现代c#特性:

选择1)

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

选择2)

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

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