Построители коллекций
Добавляйте поддержку выражений коллекций в пользовательские типы.
«Построители коллекций» — бесплатный урок C# Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Пользовательские типы в выражениях коллекций
Выражения коллекций не ограничены встроенными типами. С атрибутом [CollectionBuilder] собственный тип можно создавать с помощью синтаксиса [...].
Атрибут CollectionBuilder
Примените [CollectionBuilder(typeof(Factory), "Create")] к типу коллекции. Он задаёт имя статического метода-фабрики, который компилятор вызывает для создания экземпляров.
Сигнатура метода-построителя
Метод-построитель должен быть static, принимать единственный параметр ReadOnlySpan<T> и возвращать тип Вашей коллекции. Компилятор передаёт элементы в виде диапазона.
Минимальная пользовательская коллекция
Вот небольшая неизменяемая коллекция, которая поддерживает создание с помощью выражений коллекций через построитель.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
[CollectionBuilder(typeof(IntBagBuilder), "Create")]
class IntBag : IEnumerable<int> {
private readonly int[] items;
public IntBag(ReadOnlySpan<int> data) => items = data.ToArray();
public IEnumerator<int> GetEnumerator() => ((IEnumerable<int>)items).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator();
}
static class IntBagBuilder {
public static IntBag Create(ReadOnlySpan<int> data) => new IntBag(data);
}
IntBag bag = [1, 2, 3];
foreach (int n in bag) Console.Write(n + " "); // 1 2 3
Console.WriteLine();Почему ReadOnlySpan
Параметр-диапазон позволяет компилятору передать элементы без промежуточного выделения памяти. Построитель копирует их в нужное ему хранилище.
Требуется реализация IEnumerable
Тип коллекции должен реализовывать IEnumerable<T> с соответствующим типом элементов диапазона, чтобы компилятор знал тип элементов и мог проверять правильность использования.
Обобщённые построители
Построители могут быть обобщёнными и поддерживать MyCollection<T>. Метод-построитель принимает ReadOnlySpan<T> и возвращает MyCollection<T>.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
[CollectionBuilder(typeof(BoxBuilder), "Create")]
class Box<T> : IEnumerable<T> {
private readonly T[] items;
public Box(ReadOnlySpan<T> d) => items = d.ToArray();
public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)items).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator();
}
static class BoxBuilder {
public static Box<T> Create<T>(ReadOnlySpan<T> d) => new Box<T>(d);
}
Box<string> b = ["x", "y"];
foreach (var s in b) Console.Write(s + " "); // x y
Console.WriteLine();Преимущество неизменяемых коллекций
Именно так неизменяемые коллекции .NET, например ImmutableArray<T>, поддерживают выражения коллекций. Построитель создаёт зафиксированный экземпляр из диапазона.
using System;
using System.Collections.Immutable;
ImmutableArray<int> nums = [1, 2, 3];
Console.WriteLine(nums.Length); // 3Элементы распространения тоже работают
После добавления построителя элементы распространения автоматически работают внутри выражений коллекций этого типа, поскольку компилятор по-прежнему создаёт единый диапазон элементов.
using System;
using System.Collections.Immutable;
ImmutableArray<int> a = [1, 2];
ImmutableArray<int> all = [..a, 3, 4];
Console.WriteLine(all.Length); // 4Когда добавлять построитель
Добавьте [CollectionBuilder], когда выпускаете собственную коллекцию и хотите предоставить вызывающему коду лаконичный синтаксис [...], особенно для неизменяемых или специализированных контейнеров.
Объединение всех возможностей
Построитель состоит всего из трёх частей: атрибута, типа IEnumerable<T> и статического метода Create(ReadOnlySpan<T>). С ними Ваш тип становится полноценным целевым типом выражения коллекции.
Быстрая проверка
Проверьте требования к построителю коллекции.
Итоги
Вы узнали, как пользовательские типы поддерживают выражения коллекций.
- Примените
[CollectionBuilder(typeof(Factory), "Create")]к типу. - Фабрика представляет собой метод
static, принимающийReadOnlySpan<T>. - Тип должен реализовывать
IEnumerable<T>. - Именно так
ImmutableArray<T>принимает[...].
Часто задаваемые вопросы
Урок «Построители коллекций» бесплатный?
Да — полный текст урока «Построители коллекций» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Построители коллекций»?
Добавляйте поддержку выражений коллекций в пользовательские типы. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Построители коллекций»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Синтаксис выражений коллекций
- Элемент распространения
- Вывод типа коллекций по контексту
- Построители коллекций