C# 13: используйте params-коллекции с любым распознаваемым типом коллекции
C# 13 расширяет модификатор params за пределы массивов, поддерживая Span, ReadOnlySpan, IEnumerable и другие типы коллекций, что уменьшает шаблонный код и повышает гибкость.
Модификатор params в C# традиционно ассоциировался с типами массивов, позволяя методам принимать переменное число аргументов. Однако начиная с C# 13 вы можете использовать params-коллекции с разнообразными типами коллекций, расширяя сферу применения и делая код ещё более универсальным.
Поддерживаемые типы коллекций
Модификатор params теперь работает с несколькими распознаваемыми типами коллекций, включая:
System.Span<T>System.ReadOnlySpan<T>- типы, реализующие
System.Collections.Generic.IEnumerable<T>и при этом имеющие методAdd.
Кроме того, вы можете использовать params со следующими системными интерфейсами:
System.Collections.Generic.IEnumerable<T>System.Collections.Generic.IReadOnlyCollection<T>System.Collections.Generic.IReadOnlyList<T>System.Collections.Generic.ICollection<T>System.Collections.Generic.IList<T>
Практический пример: использование Span с params
Одна из интересных возможностей этого улучшения — использовать span в качестве параметров params. Вот пример:
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
В этом методе params позволяет передать переменное число span в метод Concat. Метод обрабатывает каждый span по очереди, демонстрируя расширенную гибкость модификатора params.
Сравнение с C# 12.0
В более ранних версиях C# ключевое слово params поддерживало только массивы, что вынуждало разработчиков вручную преобразовывать другие типы коллекций в массивы перед передачей в метод, использующий params. Этот процесс добавлял ненужный шаблонный код, например создание временных массивов или явный вызов методов преобразования.
Пример без новой возможности (до C# 13)
void PrintValues(params int[] values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
}
var list = new List<int> { 1, 2, 3 };
// Manual conversion to array
PrintValues(list.ToArray());
Пример с новой возможностью (C# 13)
void PrintValues(params IEnumerable<int> values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
}
var list = new List<int> { 1, 2, 3 };
// No conversion needed
PrintValues(list);
Новая возможность сокращает шаблонный код за счёт следующего:
- Устранение ручного преобразования – нет необходимости явно преобразовывать коллекции вроде
List<T>илиIEnumerable<T>в массивы. - Упрощение кода – вызовы методов становятся чище и читабельнее, напрямую принимая совместимые типы коллекций.
- Улучшение поддерживаемости – уменьшается повторяющийся и подверженный ошибкам код, фокус смещается на саму логику, а не на обработку преобразований.
Поведение компилятора и разрешение перегрузок
Появление params-коллекций означает изменения в поведении компилятора, особенно в отношении разрешения перегрузок. Когда метод включает параметр params типа коллекции, отличного от массива, компилятор оценивает применимость как обычной, так и расширенной формы метода.
Обработка ошибок и лучшие практики
При использовании params важно соблюдать лучшие практики, чтобы избежать распространённых ошибок:
- позиция параметра – убедитесь, что параметр
paramsявляется последним в списке формальных параметров - ограничения модификаторов – избегайте сочетания
paramsс модификаторамиin,refилиout - значения по умолчанию – не назначайте значения по умолчанию параметрам
params, это не разрешено
Подробнее можно посмотреть в спецификации возможности.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.