Toarray c что это
Перейти к содержимому

Toarray c что это

  • автор:

 

Операции ToArray и ToList

Следующие операции преобразования предоставляют простой и удобный способ преобразования последовательностей в другие типы коллекций.

ToArray

Операция ToArray создает массив типа T из входной последовательности типа T. Эта операция имеет один прототип, описанный ниже:

Эта операция берет входную последовательность source с элементами типа T и возвращает массив элементов типа Т.

Для примера, демонстрирующего работу операции ToArray, понадобится последовательность типа IEnumerable<T>. Последовательность этого типа создается вызовом операции Enumerable.Range(), которая была описана ранее. Имея такую последовательность, можно вызывать операцию ToArray для создания массива, как показано ниже:

Использование операции ToArray

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

ToList

Операция ToList создает List типа T из входной последовательности типа Т. Эта операция имеет один прототип, описанный ниже:

Данная операция принимает последовательность по имени source элементов типа T и возвращает список List элементов типа Т. Ниже демонстрируется применение операции ToList:

В приведенном коде используется массив, состоящий из названий машин. Этот массив преобразуется в список List<string>. Вот результат:

Использование операции ToList

Эта операция часто полезна для кэширования последовательности, чтобы она не могла измениться перед ее перечислением. Также, поскольку эта операция не является отложенной и выполняется немедленно, множество перечислений на созданном списке List<T> всегда видят одинаковые данные.

Оптимизация методов ToArray и ToList путём предоставления количества элементов

Методы расширения ToArray и ToList — удобный способ быстро преобразовать перечисляемую последовательность (например, Linq-запрос) в массив или в список. Однако, в них есть кое-что беспокоящее меня: оба эти метода очень неэффективны, если они не знают количество элементов в последовательности (что почти всегда происходит, когда вы используете их в Linq-запросе). Давайте сперва рассмотрим метод ToArray (ToList имеет несколько отличий, но принцип практически такой же).

В своей основе, ToArray берет последовательность и возвращает массив, который содержит все элементы исходной последовательности. Если последовательность реализовывает интерфейс ICollection<T>, ToArray использует свойство Count для размещения в памяти массива правильного размера и копирует в него элементы последовательности. Например, преобразуем в массив список пользователей:

В этом случае ToArray довольно эффективен. Давайте изменим код так, чтобы из списка пользователей извлекались только их имена и преобразовались в массив:

Теперь, аргументом для ToArray является тип IEnumerable<User>, возвращенный методом Select. IEnumerable<User> не реализовывает интерфейс ICollection<User>, поэтому ToArray не знает количества элементов и не может разместить в памяти массив подходящего размера. Он делает следующее:

  1. Сначала в памяти размещается массив маленького размера (4 элемента в текущей реализации)
  2. В массив копируются элементы, пока он не заполнится
  3. Если в источнике больше нет элементов, производится переход к п. 7
  4. В противном случае, в памяти размещается новый массив, в два раза больше предыдущего
  5. Элементы из предыдущего массива копируются в новый
  6. Производится переход к п. 2 и все повторяется
  7. Если в результате массив оказался больше чем количество элементов, он усекается: в памяти размещается новый массив с правильным размером и в него копируются элементы
  8. Полученный массив возвращается методом

Примечание от переводчика: PsyHaSTe предложил альтернативный вариант метода без явного указания count:

 

Теперь мы можем оптимизировать наш пример таким образом:

Обратите внимание, что если вы передадите меньшее количество элементов, чем на самом деле, вы получите IndexOutOfRangeException. Вы обязаны предоставить методу правильное число.
Итак, какую производительность мы теперь получим? По моим тестам эта версия ToArray приблизительно в два раза быстрее стандартной версии для больших последовательностей (тесты запускались на 1,000,000 элементов). Довольно неплохо!

Заметьте, что мы можем улучшить метод ToList похожим способом, используя конструктор класса List<T>, который позволяет задать начальную емкость списка:

Что делает .ToArray() и зачем он нужен в данном коде?

Здесь я создал переменную input и переменную output . Я хотел присвоить output перевернутое значение input , почему без .ToArray() код не работает, зачем нужен .ToArray() и что он делает я не понял.

Twiss's user avatar

Метод Reverse (как и большинство остальных методов Linq) возвращает IEnumerable , но у класса String нет конструктора, принимающего IEnumerable<char> , зато есть конструктор, принимающий массив. Метод ToArray как раз и собирает массив на основе входной последовательности IEnumerable .

Кстати, строка реализует IEnumerable<char> , поэтому вызывать Reverse можно прямо на ней, ToCharArray можно не вызывать.

Андрей NOP's user avatar

В качестве дополнения в правильному ответу @Андрей NOP, если ваша цель — развернуть строку, вам нужна более сложная техника.

Например, вот такой код поддерживает символы из старших плоскостей Unicode, а также ненормализуемые акценты:

VladD's user avatar

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.11.43304

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Toarray c что это

Gray Pipe

Лучший отвечающий

Вопрос

Здесь я создал переменную input и переменную output . Я хотел присвоить output перевернутое значение input , почему без .ToArray() код не работает, зачем нужен .ToArray() и что он делает я не понял.

  • Изменено 666KING666 16 марта 2018 г. 5:59

Ответы

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

  • Предложено в качестве ответа Liliya Muray 16 марта 2018 г. 20:32
  • Помечено в качестве ответа Alexander Rusinov Moderator 18 марта 2018 г. 11:24

Без ToArray() можно обойтись, если вместо метода расширения Reverse Вы используете статический метод Array.Reverse:

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *