Start Debugging
2025-01-02 Обновлено 2025-01-07 csharp-13csharpdotnetdotnet-9 Edit on GitHub

C# 13: используйте params-коллекции с любым распознаваемым типом коллекции

C# 13 расширяет модификатор params за пределы массивов, поддерживая Span, ReadOnlySpan, IEnumerable и другие типы коллекций, что уменьшает шаблонный код и повышает гибкость.

Модификатор params в C# традиционно ассоциировался с типами массивов, позволяя методам принимать переменное число аргументов. Однако начиная с C# 13 вы можете использовать params-коллекции с разнообразными типами коллекций, расширяя сферу применения и делая код ещё более универсальным.

Поддерживаемые типы коллекций

Модификатор params теперь работает с несколькими распознаваемыми типами коллекций, включая:

Кроме того, вы можете использовать params со следующими системными интерфейсами:

Практический пример: использование 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);

Новая возможность сокращает шаблонный код за счёт следующего:

  1. Устранение ручного преобразования – нет необходимости явно преобразовывать коллекции вроде List<T> или IEnumerable<T> в массивы.
  2. Упрощение кода – вызовы методов становятся чище и читабельнее, напрямую принимая совместимые типы коллекций.
  3. Улучшение поддерживаемости – уменьшается повторяющийся и подверженный ошибкам код, фокус смещается на саму логику, а не на обработку преобразований.

Поведение компилятора и разрешение перегрузок

Появление params-коллекций означает изменения в поведении компилятора, особенно в отношении разрешения перегрузок. Когда метод включает параметр params типа коллекции, отличного от массива, компилятор оценивает применимость как обычной, так и расширенной формы метода.

Обработка ошибок и лучшие практики

При использовании params важно соблюдать лучшие практики, чтобы избежать распространённых ошибок:

Подробнее можно посмотреть в спецификации возможности.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад