0Pricing
C# Academy · Урок

Построители коллекций

Добавляйте поддержку выражений коллекций в пользовательские типы.

«Построители коллекций» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Синтаксис выражений коллекций
  2. Элемент распространения
  3. Вывод типа коллекций по контексту
  4. Построители коллекций
← Назад к C# Academy