,你目前只在迭代列表中的項目一次,正如其他人指出的代碼。
但是,這隻會給你一個頁面的項目。如果你正在處理多個頁面,你必須爲每個頁面調用一次該代碼(因爲某處你必須增加currentPage
,對吧?)。
我的意思是,你必須做這樣的事情:
for (int currentPage = 0; currentPage < numPages; ++currentPage)
{
foreach (var item in items.Skip(currentPage*itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
}
現在,如果你這樣做是,那麼你將被序列多次迭代 - 一次爲每個頁面。第一次迭代只會到第一頁的末尾,但下一次將從第二頁的開始到結束(通過Skip()
和Take()
)迭代 - 下一個將從開始迭代到第第三頁結束。等等。
爲了避免這種情況,您可以編寫一個IEnumerable<T>
的擴展方法,將數據分割成批(您也可以將其描述爲「分頁」數據到「頁面」)。
而不是僅僅呈現IEnumerables的IEnumerable,它可以是更有用包裹各批次中的一類,以與該批次的物品沿着供應批索引,像這樣:
public sealed class Batch<T>
{
public readonly int Index;
public readonly IEnumerable<T> Items;
public Batch(int index, IEnumerable<T> items)
{
Index = index;
Items = items;
}
}
public static class EnumerableExt
{
// Note: Not threadsafe, so not suitable for use with Parallel.Foreach() or IEnumerable.AsParallel()
public static IEnumerable<Batch<T>> Partition<T>(this IEnumerable<T> input, int batchSize)
{
var enumerator = input.GetEnumerator();
int index = 0;
while (enumerator.MoveNext())
yield return new Batch<T>(index++, nextBatch(enumerator, batchSize));
}
private static IEnumerable<T> nextBatch<T>(IEnumerator<T> enumerator, int blockSize)
{
do { yield return enumerator.Current; }
while (--blockSize > 0 && enumerator.MoveNext());
}
}
此擴展方法不會緩衝數據,並且只會遍歷一次。
鑑於此擴展方法,對項目進行批處理變得更具可讀性。請注意,此示例列舉了所有頁面的所有項目,而不像OP僅通過一個頁面迭代項目的示例:
var items = Enumerable.Range(10, 50); // Pretend we have 50 items.
int itemsPerPage = 20;
foreach (var page in items.Partition(itemsPerPage))
{
Console.Write("Page " + page.Index + " items: ");
foreach (var i in page.Items)
Console.Write(i + " ");
Console.WriteLine();
}
放入中斷點並查看。 –
這只是一個分割。你是否也從循環中調用它? –