为了账号安全,请及时绑定邮箱和手机立即绑定

从IEnumerable <T>计算项目而不进行迭代?

从IEnumerable <T>计算项目而不进行迭代?

哔哔one 2019-10-25 10:30:09
private IEnumerable<string> Tables{    get    {        yield return "Foo";        yield return "Bar";    }}假设我要迭代这些并编写类似#m的#n处理。有没有一种方法可以在我的主迭代之前不进行迭代就找出m的值?我希望我能说清楚。
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

IEnumerable不支持这一点。这是设计使然。IEnumerable使用惰性评估来获取您需要的元素,然后再使用它们。


如果您想在不迭代的情况下知道项目的数量,可以使用ICollection<T>,它具有一个Count属性。


查看完整回答
反对 回复 2019-10-25
?
慕斯王

TA贡献1864条经验 获得超2个赞

的System.Linq.Enumerable.Count扩展方法IEnumerable<T>具有以下实现:


ICollection<T> c = source as ICollection<TSource>;

if (c != null)

    return c.Count;


int result = 0;

using (IEnumerator<T> enumerator = source.GetEnumerator())

{

    while (enumerator.MoveNext())

        result++;

}

return result;

因此,它尝试强制转换为ICollection<T>具有Count属性的,并在可能的情况下使用它。否则进行迭代。


因此,最好的选择是Count()在IEnumerable<T>对象上使用扩展方法,因为那样会获得最佳性能。


查看完整回答
反对 回复 2019-10-25
?
慕斯709654

TA贡献1840条经验 获得超5个赞

只需添加一些额外的信息:


该Count()扩展并不总是迭代。考虑将Linq转换为Sql,其中将计数发送到数据库,但是它不带回所有行,而是发出Sql Count()命令并返回该结果。


另外,编译器(或运行时)足够聪明,Count()如果有的话,它将调用objects 方法。因此,它不是像其他响应者所说的那样,完全无知并且总是为了计数元素而反复进行。


在许多情况下,程序员只是if( enumerable.Count != 0 )使用Any()扩展方法进行检查,因为if( enumerable.Any() ) linq的惰性评估会更有效,因为一旦确定有任何元素,它就会短路。它也更具可读性


查看完整回答
反对 回复 2019-10-25
  • 3 回答
  • 0 关注
  • 418 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信