finiteList.Reverse().Take(count).Reverse();
или
finiteList.Skip(finiteList.Count() - count)
В этом есть некоторые издержки, поэтому лучше использовать пользовательский метод.
Обновление: Пользовательский метод
public static class EnumerableExtensions
{
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
{
if (source == null) throw new ArgumentNullException("source");
if (count < 0) throw new ArgumentOutOfRangeException("count");
if (count == 0) yield break;
var queue = new Queue<T>(count);
foreach (var t in source)
{
if (queue.Count == count) queue.Dequeue();
queue.Enqueue(t);
}
foreach (var t in queue)
yield return t;
}
}
Обновление: Изменен небольшой код с идеями из ответа dtb: -)
Комментарий для Bear: Посмотрите на этот пример:
var lastFive = Enumerable.Range(1, 10).TakeLast(5);
var lastFive2 = Enumerable.Range(1, 10).TakeLast2(5); //Bear´s way
Queue<int> q = (Queue<int>)lastFive2;
q.Dequeue();
//Is lastFive2 still last five? no...
Вы можете потенциально изменить значения lastFive2
, и, следовательно, этот подход может быть небезопасным или, по крайней мере, не функциональным.
.
Что я имел в виду под сейфом, так это:
var lastFive2 = Enumerable.Range(1, 10).TakeLast2(5); //Bear´s way
//some = Some method which you don't control - it could be from another assembly which represents a crazy plugin etc.
some(lastFive2);
//Now what?
В этих случаях вам придется сделать копию, чтобы быть уверенным.Но в большинстве случаев ваш путь будет в порядке - и немного более эффективным, чем этот, поэтому +1:)
Идея состоит в том, чтобы использовать очередь, которая имеет только внутренний Enqueue и т. Д.