检查IEnumerable是否具有任何行而不枚举整个列表

时间:2013-06-04 10:29:22

标签: c# .net linq lazy-loading ienumerable

我有以下方法返回IEnumerable类型T。除了yield return延迟加载 IEnumerable之外,该方法的实施并不重要。这是必要的,因为结果可能有数百万项。

public IEnumerable<T> Parse()
{
    foreach(...)
    {
        yield return parsedObject;
    }
}

问题:

我有以下属性可用于确定IEnumerable是否有任何项目:

public bool HasItems
{
    get
    {
        return Parse().Take(1).SingleOrDefault() != null;
    }
}

是否有更好的方法可以做到这一点?

2 个答案:

答案 0 :(得分:33)

如果序列中有任何元素,

IEnumerable.Any()将返回true,如果序列中没有元素,则false将返回{{1}}。此方法不会迭代整个序列(只有最多一个元素),因为如果它超过第一个元素,它将返回true,否则返回false。

答案 1 :(得分:2)

类似于Howto: Count the items from a IEnumerable<T> without iterating?Enumerable意味着是 lazy ,前瞻性“列表”,就像量子力学一样,调查它的行为会改变其状态。

查看确认:https://dotnetfiddle.net/GPMVXH

    var sideeffect = 0;
    var enumerable = Enumerable.Range(1, 10).Select(i => {
        // show how many times it happens
        sideeffect++;
        return i;
    });

    // will 'enumerate' one item!
    if(enumerable.Any()) Console.WriteLine("There are items in the list; sideeffect={0}", sideeffect);

enumerable.Any()是检查列表中是否有任何项目的最简洁方法。您可以尝试投射到不是懒惰的东西,例如if(null != (list = enumerable as ICollection<T>) && list.Any()) return true

或者,您的方案可能允许使用Enumerator并在枚举前进行初步检查:

var e = enumerable.GetEnumerator();
// check first
if(!e.MoveNext()) return;
// do some stuff, then enumerate the list
do {
    actOn(e.Current);  // do stuff with the current item
} while(e.MoveNext()); // stop when we don't have anything else
相关问题