TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3362 486
День 2805. #ЧтоНовенького #NET11
Аргументы в Выражениях Коллекций в C#15

В C#15 реализовано точечное улучшение выражений создания коллекций: возможность передавать аргументы с помощью элемента `with(…)`, указываемого в начале выражения.

Если вы уже используете выражения создания коллекций из C#12, это нововведение устраняет распространённое неудобство: теперь можно передавать аргументы (характерные для конструкторов или фабричных методов) непосредственно внутри […].

Сравнение C# версий 12, 13 и 15
C#12 - Добавлены выражения создания коллекций ([…]) и spread-оператор (..):
int[] values = [1, 2, 3];
int[] all = [0, ..values, 4];


C#13 - Расширена поддержка params для разных типов коллекций (не только массивов) в параметрах методов:
csharp 
public void LogValues(params Span<int> numbers)
{
// …
}
LogValues(1, 2, 3);


C#15 - Добавлен элемент with(…) в начало выражений создания коллекций
List<int> numbers = 
[with(capacity: 100), 1, 2, 3, ..more];


with(…) предоставляет аргументы для создания коллекции, где это поддерживается (параметры конструктора, построитель Create(…), отдельные сигнатуры интерфейсов).
При этом with(…) должен быть первым элементом.

Практические примеры
1) Предварительное определение размера коллекций для обеспечения читаемости и ясности намерений
List<int> ids = [with(capacity: 256), ..sourceIds];

Это позволяет выполнить инициализацию в рамках одного выражения и делает ваш замысел очевидным.

2) Сценарии использования построителей коллекций
Для построителей коллекций C#15 поддерживает дополнительные параметры метода Create(…):
static MyCollection<T>
Create(SomeOption option, ReadOnlySpan<T> items)
{
// …
}

Использование:
Tags tags = [with(StringComparer.OrdinalIgnoreCase), "CSharp", "CSHARP", "csharp", "dotnet"];
Tags newTags = [with(), "CSharp", "CSHARP", "csharp", "dotnet"];
Tags oldTags = ["CSharp", "CSHARP", "csharp", "dotnet"];

[CollectionBuilder(typeof(Tags), nameof(Create))]
internal sealed class Tags(
string[] values,
StringComparer comparer)
: HashSet<string>(values, comparer)
{
public static Tags Create(
StringComparer comparer,
ReadOnlySpan<string> items)
=> new([.. items], comparer);

public static Tags Create(ReadOnlySpan<string> items)
=> new([.. items], StringComparer.OrdinalIgnoreCase);
}


Ограничения и нюансы
1. Если целевым типом является массив или span, использование with(…) невозможно.
2. Аргументы внутри with(…) не могут иметь тип dynamic.
3. Согласно замыслу, аргументы with(…) игнорируются при принятии решений о преобразовании или выводе типов (по аналогии с new(…)).
4. Действуют обычные правила выбора перегрузки конструктора или построителя. Если подходят несколько вариантов, возможна неоднозначность.

Почему важны аргументы выражений коллекций в C#15
C#15 улучшает инициализацию коллекций в одно выражение, обеспечивая:
- Более ясное выражение намерений (указание вместимости, опций, компараторов и т.д., где это поддерживается);
- Сокращение числа отдельных инструкций инициализации;
- Более чистый API для пользовательских построителей коллекций.

Источник: https://laurentkempe.com/2026/09/26/csharp-15-collection-expression-arguments/
  • 👎 1
More from @netdeveloperdiary
  1. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  2. Oct 3, 2026Post #3360
  3. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
  4. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  5. Oct 1, 2026Post #3357
  6. Sep 30, 2026Post #3356
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →