collection.Skip(Math.Max(0, collection.Count() - N));
Этот подход сохраняет порядок элементов без зависимости от какой-либо сортировки и обладает широкой совместимостью между несколькими поставщиками LINQ.
Важно позаботиться о том, чтобы не звонить Skip
с отрицательным номером. Некоторые провайдеры, такие как Entity Framework, будут генерировать ArgumentException, когда представлены с отрицательным аргументом Звонок на Math.Max
аккуратно избегает этого.
В приведенном ниже классе есть все необходимое для методов расширения: статический класс, статический метод и использование ключевого слова this
.
public static class MiscExtensions
{
// Ex: collection.TakeLast(5);
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int N)
{
return source.Skip(Math.Max(0, source.Count() - N));
}
}
Краткое примечание по производительности:
Поскольку вызов Count()
может вызвать перечисление определенных структур данных, такой подход может вызвать два прохода по данным. На самом деле это не проблема для большинства перечислимых; фактически уже существуют оптимизации для списков, массивов и даже запросов EF для оценки операции Count()
за O (1).
Если, однако, вы должны использовать перечислимое только для пересылки и хотели бы избежать двухпроходного прохождения, рассмотрите однопроходный алгоритм, например Lasse V. Karlsen или Mark Byers описать. Оба эти подхода используют временный буфер для хранения элементов при перечислении, которые выдаются после того, как будет найден конец коллекции.