关于c#:当一个Enumerable在Linq中有超过X个元素时,早期返回

Early return when an Enumerable has more then X elements in Linq

LINQ中最有效的编写方法是什么:

return enumerable.Count() > x;

我至少在寻找一种解决方案:

  • 不包括计算整个可枚举的。
  • 最好是标准.NET LINQ。
  • 应该在不同的提供者上工作。

请注意,enumerable.Any()在0以上的情况下工作得很好,但我正在寻找一个检查多于x的解决方案。

例子:

想象一个使用yield return构建的非常大的可枚举的。


简单点怎么样:

1
return enumerable.Skip(x).Any();

我想这就是你要找的。


没有内置的LINQ方法可以提供最有效的解决方案。基本上,您需要检查IEnumerable是否具有count属性(通过ICollection),如果没有枚举它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static class MoreEnumerable
{
    public static bool HasAtLeast<T>(this IEnumerable<T> source, int count)
    {
        if (source is ICollection<T>)
        {
            return ((ICollection<T>)source).Count > count;
        }
        else if (source is ICollection)
        {
            return ((ICollection)source).Count > count;
        }

        return source.Skip(count).Any();
    }
}


如果你只想用LINQ,我会用

1
enumerable.Take(x).Count() == x

尽管我更喜欢Selman22方法


我想你想要这样的东西:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static bool LazyCount<T>(this IEnumerable<T> source, int count)
{
    var enumerator = source.GetEnumerator();

    int i = 0;

    while(enumerator.MoveNext())
    {
        i++;
        if(i > count) return true;
    }
    return false;
}

用法如下:

1
return enumerable.LazyCount(x);

注意:我不擅长命名,但您应该了解这个想法,您可以根据自己的喜好修改它。


What is the most performant (and beautiful) way in Linq to write:
return enumerable.Count() > x;

只是有什么问题:

1
return enumerable.Count() > x;

如果实际类型的enumerable也实现了ICollection,那么它只返回ICollection.Count,这通常是O(1)操作。对于IQueryable,大多数查询提供者都会将其转换为SELECT COUNT(*) FROM ...,这几乎是您所能得到的最快速度。

因此,与Count相比,执行性能更好的边缘案例相对较少;可能很少有足够多的案例试图为它们编写代码会适得其反。


如果你想知道你是否有5个以上的孩子,你可以做以下的事情

enumerable.Take(6).Count() == 6