private IEnumerable<string> Tables
{
get
{
yield return "Foo";
yield return "Bar";
}
}
假设我想要迭代这些并写一些类似于processing #n of #m的东西。
有没有一种方法可以让我在不进行主迭代的情况下求出m的值?
我希望我讲清楚了。
private IEnumerable<string> Tables
{
get
{
yield return "Foo";
yield return "Bar";
}
}
假设我想要迭代这些并写一些类似于processing #n of #m的东西。
有没有一种方法可以让我在不进行主迭代的情况下求出m的值?
我希望我讲清楚了。
当前回答
IEnumerable<T>上的System.Linq.Enumerable.Count扩展方法有以下实现:
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;
因此,它尝试强制转换为具有Count属性的ICollection<T>,并尽可能使用该属性。否则它会迭代。
因此,最好的方法是在IEnumerable<T>对象上使用Count()扩展方法,因为这样可以获得最好的性能。
其他回答
除了你的直接问题(已经得到了否定的回答),如果你想在处理一个可枚举对象时报告进度,你可能想看看我的博客文章《在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
};
这里有一个关于惰性求值和延迟执行的很好的讨论。基本上你必须物化这个列表才能得到这个值。
IEnumerable.Count()函数的结果可能是错误的。这是一个非常简单的测试样本:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
namespace Test
{
class Program
{
static void Main(string[] args)
{
var test = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
var result = test.Split(7);
int cnt = 0;
foreach (IEnumerable<int> chunk in result)
{
cnt = chunk.Count();
Console.WriteLine(cnt);
}
cnt = result.Count();
Console.WriteLine(cnt);
Console.ReadLine();
}
}
static class LinqExt
{
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkLength)
{
if (chunkLength <= 0)
throw new ArgumentOutOfRangeException("chunkLength", "chunkLength must be greater than 0");
IEnumerable<T> result = null;
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
result = GetChunk(enumerator, chunkLength);
yield return result;
}
}
}
static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int chunkLength)
{
int x = chunkLength;
do
yield return source.Current;
while (--x > 0 && source.MoveNext());
}
}
}
结果必须是(7,7,3,3),但实际结果是(7,7,3,17)
它可能不会产生最好的性能,但你可以使用LINQ来计算IEnumerable中的元素:
public int GetEnumerableCount(IEnumerable Enumerable)
{
return (from object Item in Enumerable
select Item).Count();
}
你可以使用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());
}
}
你会得到结果'2'。