Обратный и обратный

#c# #reverse

#c# #обратный

Вопрос:

У меня есть вопрос об изменении элементов списка в C #.

Конечная цель — получить последние N элементов списка.

Предположим, у меня есть список десятичных дробей.

 List<decimal> listOfDecimals = new List<decimal>() { 1.5m, 2.4m, 3.6m, 0.1m };
  

Это моя попытка получить список, содержащий последние 2 элемента listOfDecimals .

 List<decimal> listOfLastTwoElements = listOfDecimals.Reverse<decimal>().Take<decimal>(2).Reverse<decimal>().ToList<decimal>();
  

Мой вопрос в том, что если я заменил Reverse<>() на Reverse(), возникает синтаксическая ошибка, отмеченная VS.

Может кто-нибудь, пожалуйста, дайте мне знать, когда я должен использовать Reverse() , а когда использовать Reverse<>() ?

Комментарии:

1. Вы можете просто сделать var v = listOfDecimals.Skip(listOfDecimals.Count -2).ToList();

2. @NikhilAgrawal Спасибо за предложение. Но можете ли вы также сообщить мне, когда я должен использовать один над другим?

3. Кроме того, если вы хотите устранить неоднозначность между Enumerable.Reverse<T> расширением и List<T>.Reverse , использование AsEnumerable<T> расширения сделает синтаксис более понятным. Например., listOfDecimals.AsEnumerable().Reverse().Take(2).Reverse().ToList(); . Таким образом, вам не нужно указывать параметр универсального типа <decimal> снова и снова.

Ответ №1:

Это потому, что сам список имеет обратный метод. Этот обратный метод ничего не возвращает.

Обратный метод on List<T> имеет приоритет над методом расширения on IEnumerable<T> . Сбивает с толку то, что когда у вас просто есть IEnumerable<T> , вы можете использовать Reverse() без аргумента типа. Затем вывод типа компилятора разрешает аргумент универсального типа. Таким образом, метод расширения выглядит так же, как метод on List<T> .

 var reversed1 = Enumerable.Empty<int>().Reverse(); // works
var reversed2 = Enumerable.Empty<int>().Reverse<int>(); // works and is the same as the line above.

var reversed3 = new List<int>().Reverse(); // does not work
var reversed4 = new List<int>().Reverse<int>(); // works
  

Ответ №2:

Reverse() — это метод List<T> , Reverse<T>() это (расширение) метод IEnumerable<T> , так что включает List<T> в себя .

Если вы хотите взять последние 2 элемента IEnumerable, вы можете просто сделать Last(2) . Это вернет an IEnumerable<T> , поэтому, если вы хотите, чтобы это было в списке, вы должны вызвать ToList это.

 List<T> also has a method `RemoveRange()`, so if you want to remove all but the last 2 elements:

listOfDecimals.RemoveRange(0, listOfDecimals.Count - 2)