private IEnumerable<string> Tables
{
get
{
yield return "Foo";
yield return "Bar";
}
}
假设我想在迭代过程中编写类似于处理 #n of #m 的内容。
在我的主要迭代之前,有没有一种方法可以找出 m 的值?
希望我表达清楚了。
private IEnumerable<string> Tables
{
get
{
yield return "Foo";
yield return "Bar";
}
}
假设我想在迭代过程中编写类似于处理 #n of #m 的内容。
在我的主要迭代之前,有没有一种方法可以找出 m 的值?
希望我表达清楚了。
在.NET 6中,LINQ有了一种新的方法。
观看https://www.youtube.com/watch?v=sIXKpyhxHR8
Tables.TryGetNonEnumeratedCount(out var count)
简化所有答案。
IEnumerable没有Count函数或属性。要获取此功能,您可以使用Linq获取计数或使用foreach等方法存储count变量。
如果您有:
IEnumerable<> 产品
那么:
声明:“using System.Linq;”
计数:
products.ToList().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
};
.method public hidebysig static int32 Count<TSource>(class
[mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource> source) cil managed
{
.custom instance void System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 85 (0x55)
.maxstack 2
.locals init (class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource> V_0,
class [mscorlib]System.Collections.ICollection V_1,
int32 V_2,
class [mscorlib]System.Collections.Generic.IEnumerator`1<!!TSource> V_3)
IL_0000: ldarg.0
IL_0001: brtrue.s IL_000e
IL_0003: ldstr "source"
IL_0008: call class [mscorlib]System.Exception System.Linq.Error::ArgumentNull(string)
IL_000d: throw
IL_000e: ldarg.0
IL_000f: isinst class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: brfalse.s IL_001f
IL_0018: ldloc.0
IL_0019: callvirt instance int32 class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>::get_Count()
IL_001e: ret
IL_001f: ldarg.0
IL_0020: isinst [mscorlib]System.Collections.ICollection
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: brfalse.s IL_0030
IL_0029: ldloc.1
IL_002a: callvirt instance int32 [mscorlib]System.Collections.ICollection::get_Count()
IL_002f: ret
IL_0030: ldc.i4.0
IL_0031: stloc.2
IL_0032: ldarg.0
IL_0033: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource>::GetEnumerator()
IL_0038: stloc.3
.try
{
IL_0039: br.s IL_003f
IL_003b: ldloc.2
IL_003c: ldc.i4.1
IL_003d: add.ovf
IL_003e: stloc.2
IL_003f: ldloc.3
IL_0040: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
IL_0045: brtrue.s IL_003b
IL_0047: leave.s IL_0053
} // end .try
finally
{
IL_0049: ldloc.3
IL_004a: brfalse.s IL_0052
IL_004c: ldloc.3
IL_004d: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0052: endfinally
} // end handler
IL_0053: ldloc.2
IL_0054: ret
} // end of method Enumerable::Count
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)
IEnumerable<T> enumList = ReturnFromSomeFunction();
int count = new List<T>(enumList).Count;
虽然可能不会产生最佳性能,但您可以使用LINQ来计算IEnumerable中的元素数量:
public int GetEnumerableCount(IEnumerable Enumerable)
{
return (from object Item in Enumerable
select Item).Count();
}
?System.Linq.Enumerable.Count(myIEnumerable)
12