Intereting Posts
Изменения исходного значения не отражаются в переменной ссылочных типов Ограничение доступа к публичному сетевому устройству для определенных объектов (C #) Отладка C ++ / Cli: и никаких локалей Зарегистрировать null как экземпляр в контейнере Unity Как добавить дополнительные windows инструментов в расширение Visual Studio? Поставщик веб-сайта MVC и локализация Создание и сохранение PDF-файла Как отключить привязку модели по умолчанию для определенного classа Как создать единый список пар объектов из двух списков в C #? В чем разница между использованием оператора и добавлением ссылки? Запись в MemoryStream с StreamWriter возвращается пустым «Newtonsoft.Json …» существует как в «Blend \ Newtonsoft.Json.dll», так и «Solution \ packages \ … \ Как я могу получить список дочерних процессов для данной службы на C #? Лучший способ получить счетчик IEnumerable Проверьте, содержит ли строка один из 10 символов

Почему существует две совершенно разные версии Reverse для List и IEnumerable?

Для объекта List мы имеем метод Reverse () .
Он отменяет порядок списка «на месте», он ничего не возвращает.

Для объекта IEnumerable у нас есть метод расширения, называемый Reverse () .
Он возвращает другой IEnumerable.

Мне нужно выполнить итерацию в обратном порядке через список, поэтому я не могу напрямую использовать второй метод, потому что я получаю список, и я не хочу его менять, просто повторяю назад.

Поэтому я могу это сделать:

 for(int i = list.Count - 1; i >=0; i--) 

Или же

 foreach(var item in list.AsEnumerable().Reverse()) 

Я нашел его менее читаемым, чем если бы у меня был IEnumerable, просто сделайте

 foreach(var item in list.Reverse()) 

Я не могу понять, почему эти 2 метода были реализованы таким образом, с тем же именем. Это довольно раздражает и запутывает.

Почему нет расширения под названием BackwardsIterator () вместо Reverse () для всех IEnumerable?

Меня очень интересует историческая причина этого выбора, больше, чем «как это сделать»!

    Стоит отметить, что метод списка намного старше метода расширения. Именование, вероятно, сохранилось так же, как « Reverse кажется более кратким, чем BackwardsIterator .

    Если вы хотите обойти версию списка и перейти к методу расширения, вам нужно обработать список как IEnumerable :

     var numbers = new List(); numbers.Reverse(); // hits list (numbers as IEnumerable).Reverse(); // hits extension 

    Или вызовите метод расширения как статический метод:

     Enumerable.Reverse(numbers); 

    Обратите внимание, что в версии Enumerable необходимо выполнить итерацию перечислимого элемента целиком, чтобы начать повторять его в обратном порядке. Если вы планируете делать это несколько раз по тому же перечисляемому, считайте, что вы постоянно меняете порядок и повторяете его в обычном режиме.

    Тогда напишите свой собственный BackwardsIterator!

     public static IEnumerable BackwardsIterator(this List lst) { for(int i = lst.Count - 1; i >=0; i--) { yield return lst[i]; } } 

    Разница связана с тем, что List является classом, а IEnumerable – интерфейсом. Это означает, что объект List имеет одну реализацию (ну, это реализация), и эффект Reverse гарантированно сохраняется во внутреннем состоянии объекта.

    С IEnumerable он отличается: любой объект может его реализовать, без обязательства реализовать метод Reverse , потому что он не является частью интерфейса. Метод расширения Reverse() может только перечислять перечислитель IEnumerable в обратном порядке, но никогда не изменять внутреннее состояние объекта.

    Но List.Reverse уже существовал, когда был введен Enumerable и его методы расширения. Если бы они были изобретены в то же время, List.Reverse также мог бы быть апатридом для единообразия. Кто знает.