dasblinkenlight является, вероятно, лучше всего, если вы счастливы ограничить себя коллекциями, где вы знаете длину заранее. Если вы этого не сделаете, вы можете добавить метод расширения, как это (непроверенные):
public static IEnumerable<T> SkipEnd<T>(this IEnumerable<T> source,
int countToSkip)
{
// TODO: Validation
T[] buffer = new T[countToSkip];
int index = 0;
bool returning = false;
foreach (var item in source)
{
if (returning)
{
yield return buffer[index];
}
buffer[index] = item;
index++;
if (index == countToSkip)
{
index = 0;
returning = true;
}
}
}
Вы бы затем использовать:
var elements = original.Skip(1).SkipEnd(1);
Реализация выше содержит свой собственный циклический буфер, но вы можете легко использовать Queue<T>
, если хотите. Например:
public static IEnumerable<T> SkipEnd<T>(this IEnumerable<T> source,
int countToSkip)
{
// TODO: Validation
Queue<T> queue = new Queue<T>(countToSkip);
foreach (var item in source)
{
if (queue.Count == countToSkip)
{
yield return queue.Dequeue();
}
queue.Enqueue(item);
}
}
Эта версия будет изящно возвращать пустое перечисление без каких-либо специальных проверок – thewyzard