seb*_*mez 304 .net c# ienumerable
private IEnumerable<string> Tables
{
get
{
yield return "Foo";
yield return "Bar";
}
}
Run Code Online (Sandbox Code Playgroud)
假设我想迭代那些并写一些像#m的#n处理.
有没有一种方法可以在我的主迭代之前找到m的值而不进行迭代?
我希望我清楚自己.
Men*_*elt 322
IEnumerable
不支持这个.这是设计的.IEnumerable
在您需要之前使用延迟评估来获取您要求的元素.
如果你想知道项目的数量,而不是迭代它们你可以使用ICollection<T>
,它有一个Count
属性.
Dan*_*ker 208
在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;
Run Code Online (Sandbox Code Playgroud)
所以它试图转换为ICollection<T>
具有Count
属性的属性,并在可能的情况下使用它.否则它会迭代.
因此,最好的Count()
办法是在IEnumerable<T>
对象上使用扩展方法,因为这样可以获得最佳性能.
Rob*_*son 86
只需添加额外的一些信息:
该Count()
扩展并不总是迭代.考虑Linq to Sql,其中计数进入数据库,但不是返回所有行,而是发出Sql Count()
命令并返回该结果.
此外,编译器(或运行时)足够智能,Count()
如果有一个对象方法,它将调用它.所以它并不像其他响应者所说的那样,完全无知并且总是为了计算元素而迭代.
在许多情况下,程序员只是if( enumerable.Count != 0 )
使用Any()
扩展方法进行检查,因为if( enumerable.Any() )
linq的惰性评估效率更高,因为一旦确定有任何元素,它就会短路.它也更具可读性
Joe*_*orn 12
我的一位朋友有一系列博客文章,说明了为什么你不能这样做.他创建了返回IEnumerable的函数,其中每次迭代返回下一个素数,一直到ulong.MaxValue
,并且在您要求之前不会计算下一个项目.快速流行问题:返回了多少项?
这是帖子,但它们有点长:
Chr*_*man 10
没有迭代,IEnumerable不能计数.
在"正常"情况下,实现IEnumerable或IEnumerable <T>的类(例如List <T>)可以通过返回List <T> .Count属性来实现Count方法.但是,Count方法实际上不是在IEnumerable <T>或IEnumerable接口上定义的方法.(事实上,唯一的一个是GetEnumerator.)这意味着无法为它提供特定于类的实现.
相反,Count它是一个扩展方法,在静态类Enumerable上定义.这意味着它可以在IEnumerable <T>派生类的任何实例上调用,而不管该类的实现如何.但它也意味着它在一个地方实施,在任何这些类之外.这当然意味着它必须以完全独立于这些类的内部的方式实现.唯一这样的计数方法是通过迭代.
您可以使用System.Linq.
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
private IEnumerable<string> Tables
{
get {
yield return "Foo";
yield return "Bar";
}
}
static void Main()
{
var x = new Test();
Console.WriteLine(x.Tables.Count());
}
}
Run Code Online (Sandbox Code Playgroud)
你会得到结果'2'.
我认为最简单的方法是做到这一点
Enumerable.Count<TSource>(IEnumerable<TSource> source)
Run Code Online (Sandbox Code Playgroud)
超越您的直接问题(已经完全回答了否定),如果您希望在处理可枚举时报告进度,您可能需要查看我的博客帖子报告Linq查询期间的进度.
它可以让你这样做:
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (sender, e) =>
{
// pretend we have a collection of
// items to process
var items = 1.To(1000);
items
.WithProgressReporting(progress => worker.ReportProgress(progress))
.ForEach(item => Thread.Sleep(10)); // simulate some real work
};
Run Code Online (Sandbox Code Playgroud)
小智 5
我在方法中使用这种方式来检查传入的IEnumberable
内容
if( iEnum.Cast<Object>().Count() > 0)
{
}
Run Code Online (Sandbox Code Playgroud)
在这样的方法中:
GetDataTable(IEnumberable iEnum)
{
if (iEnum != null && iEnum.Cast<Object>().Count() > 0) //--- proceed further
}
Run Code Online (Sandbox Code Playgroud)
LINQ for .NET 6 中有一种新方法观看https://www.youtube.com/watch?v=sIXKpyhxHR8
Tables.TryGetNonEnumeratedCount(out var count)
Run Code Online (Sandbox Code Playgroud)
小智 5
简化所有答案。
IEnumerable 没有 Count 函数或属性。为此,您可以存储计数变量(例如,使用 foreach)或使用Linq求解来获取计数。
如果你有:
IEnumerable<> 产品
然后:
声明:“使用 System.Linq;”
计数:
产品.ToList().Count