SELECT и проекция
Преобразуйте данные в новые формы
«SELECT и проекция» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Что означает проекция
Select преобразует каждый элемент последовательности в новую форму. Это называется проекцией.
Он принимает лямбда-выражение, преобразующее один элемент в результат, и возвращает последовательность этих результатов, не изменяя исходную последовательность.
using System;
using System.Linq;
int[] nums = { 1, 2, 3, 4 };
var squares = nums.Select(n => n * n);
Console.WriteLine(string.Join(", ", squares));Изменение типа
Проекция может полностью изменить тип элементов. Преобразование int в string создаёт IEnumerable<string>.
Тип результата определяется по возвращаемому типу лямбда-выражения, поэтому компилятор отслеживает его за Вас.
using System;
using System.Linq;
int[] nums = { 10, 20, 30 };
var labels = nums.Select(n => $"Item #{n}");
foreach (var l in labels) Console.WriteLine(l);Проецирование свойств
Частый вариант применения — извлечь одно свойство из объектов. Select(p => p.Name) превращает список объектов в список имён.
Так данные сужаются до нужной части перед дальнейшей обработкой или отображением.
using System;
using System.Linq;
using System.Collections.Generic;
record User(string Name, int Age);
var users = new List<User> { new("Ana", 30), new("Bo", 25) };
var names = users.Select(u => u.Name);
Console.WriteLine(string.Join(", ", names));Результаты анонимного типа
Можно выполнить проекцию в анонимный тип, чтобы сохранить вместе несколько полей. Используйте new { ... } внутри лямбда-выражения.
Компилятор на лету создаёт класс со свойствами, доступными только для чтения. Это идеально подходит для формирования промежуточных результатов.
using System;
using System.Linq;
using System.Collections.Generic;
record User(string Name, int Age);
var users = new List<User> { new("Ana", 30), new("Bo", 25) };
var shaped = users.Select(u => new { u.Name, IsAdult = u.Age >= 18 });
foreach (var s in shaped) Console.WriteLine($"{s.Name}:{s.IsAdult}");Select с индексом
Как и Where, Select имеет перегрузку, предоставляющую индекс, отсчитываемый от нуля. Лямбда-выражение принимает (element, index).
Это удобно для нумерации элементов или сопоставления каждого значения с его позицией.
using System;
using System.Linq;
string[] tasks = { "Wake", "Eat", "Code" };
var numbered = tasks.Select((t, i) => $"{i + 1}. {t}");
foreach (var n in numbered) Console.WriteLine(n);Проекция в синтаксисе запросов
В синтаксисе запросов предложение select выполняет проекцию. Можно выбрать сам элемент или любое выражение, основанное на нём.
Сочетайте его с where, чтобы в одном понятном запросе выполнить фильтрацию и сформировать нужную структуру.
using System;
using System.Linq;
int[] nums = { 1, 2, 3, 4, 5 };
var result = from n in nums
where n % 2 == 1
select n * 10;
Console.WriteLine(string.Join(", ", result));SelectMany выполняет выравнивание
Если каждый элемент преобразуется в коллекцию, Select создаёт последовательность последовательностей. SelectMany объединяет их в одну последовательность.
Это эквивалент вложенного цикла в LINQ, который объединяет внутренние результаты.
using System;
using System.Linq;
using System.Collections.Generic;
var groups = new List<int[]> { new[] {1, 2}, new[] {3, 4} };
var flat = groups.SelectMany(g => g);
Console.WriteLine(string.Join(", ", flat));Проекция тоже выполняется отложенно
Select использует ту же модель отложенного выполнения. Лямбда-выражение преобразования запускается только при перечислении последовательности.
Поэтому построение проекции не требует больших затрат: работа выполняется при переборе или материализации результата.
using System;
using System.Linq;
int runs = 0;
int[] nums = { 1, 2, 3 };
var q = nums.Select(n => { runs++; return n; });
Console.WriteLine($"Before: {runs}");
foreach (var _ in q) { }
Console.WriteLine($"After: {runs}");Сначала фильтрация, затем проекция
Порядок важен для ясности и эффективности: сначала фильтруйте с помощью Where, затем выполняйте проекцию с помощью Select, чтобы преобразовывать только сохраняемые элементы.
Этот конвейер читается сверху вниз и не тратит ресурсы на ненужное проецирование.
using System;
using System.Linq;
int[] nums = { 1, 2, 3, 4, 5, 6 };
var result = nums.Where(n => n % 2 == 0)
.Select(n => n * n);
Console.WriteLine(string.Join(", ", result));Проецирование в новую запись
Вместо анонимных типов можно выполнить проекцию в именованный тип или record. Это полезно, когда результаты выходят за границы метода, поскольку анонимные типы нельзя вернуть под известным именем.
Так же создаются объекты передачи данных из более богатых доменных объектов.
using System;
using System.Linq;
using System.Collections.Generic;
record User(string Name, int Age);
record Summary(string Name);
var users = new List<User> { new("Ana", 30) };
var dtos = users.Select(u => new Summary(u.Name));
foreach (var d in dtos) Console.WriteLine(d.Name);Select сохраняет порядок и количество
В отличие от Where, Select никогда не добавляет и не удаляет элементы — он преобразует их один к одному. В результате столько же элементов, сколько было во входных данных, и в том же порядке.
Если нужно уменьшить количество элементов, используйте фильтрацию; если нужно получить несколько элементов из каждого, используйте SelectMany.
using System;
using System.Linq;
int[] nums = { 5, 1, 9 };
var doubled = nums.Select(n => n * 2);
Console.WriteLine($"In:{nums.Length} Out:{doubled.Count()}");Быстрая проверка
Выберите подходящий оператор для задачи.
Итоги
Select проецирует каждый элемент в новую форму — свойство, строку, анонимный тип или запись, — сохраняя соответствие один к одному, количество и порядок. У него есть перегрузка с индексом, и он выполняется отложенно.
SelectMany выравнивает вложенные последовательности. Далее мы отсортируем и сгруппируем сформированные данные.
Часто задаваемые вопросы
Урок «SELECT и проекция» бесплатный?
Да — полный текст урока «SELECT и проекция» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «SELECT и проекция»?
Преобразуйте данные в новые формы Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «SELECT и проекция»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- WHERE и фильтрация
- SELECT и проекция
- OrderBy и группировка
- Агрегаты и ToList