Узнайте, как управлять коллекциями данных с помощью List<T> в C#

Это вводное руководство содержит общие сведения о языке C# и классе List<T>.

Предварительные требования

Для работы с руководством вам потребуется компьютер, настроенный для разработки в локальной среде. Инструкции по установке и общие сведения о разработке приложений в .NET см. в статье Настройка локальной среды .

Если вы предпочитаете выполнять код без настройки локальной среды, ознакомьтесь с интерактивной версией этого руководства в браузере.

Пример простого списка

Создайте каталог с именем list-tutorial. Откройте этот каталог и выполните команду dotnet new console.

Важно!

В шаблонах C# для .NET 6 используются операторы верхнего уровня. Приложение может не соответствовать коду, приведенному в этой статье, если вы уже выполнили обновление до .NET 6. Дополнительные сведения см. в статье Новые шаблоны C# для создания инструкций верхнего уровня.

Пакет SDK для .NET 6 также добавляет набор неявныхglobal using директив для проектов, использующих следующие пакеты SDK:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

Эти неявные директивы global using включают наиболее распространенные пространства имен для соответствующего типа проектов.

Дополнительные сведения см. в статье о директивах неявного использования.

Откройте Program.cs в любом редакторе и замените существующий код следующим:

List<string> names = ["<name>", "Ana", "Felipe"];
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

Замените <name> собственным именем. Сохраните Program.cs. Введите в окне консоли команду dotnet run для тестирования.

Вы создали список строк, добавили три имени в этот список и вывели имена прописными буквами. Для циклического прохода по списку вы примените концепции, которые изучили в предыдущих руководствах.

В коде для отображения имен используется функция интерполяции строк. Если перед string добавить символ $, код C# можно внедрять в объявление строки. Фактическая строка заменяет код C# генерируемым значением. В этом примере она заменяет {name.ToUpper()} именами, буквы каждого из которых преобразованы в прописные, так как вызван метод ToUpper.

Продолжим изучение.

Изменение содержимого списка

В созданной коллекции используется тип List<T>. При применении такого типа сохраняются последовательности элементов. Тип элементов указывается в угловых скобках.

Важный аспект типа List<T> — возможность увеличения или уменьшения, что позволяет добавлять или удалять элементы. Добавьте этот код в конец программы:

Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

В конец списка добавлены еще два имени. При этом одно имя удалено. Сохраните файл и введите dotnet run для тестирования.

List<T> позволяет добавлять ссылки на отдельные элементы по индексу. Поместите индекс между токенами [ и ] после имени списка. Для первого индекса в C# используется значение 0. Добавьте следующий код сразу после добавленного фрагмента и протестируйте его:

Console.WriteLine($"My name is {names[0]}");
Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

Доступ к индексу за пределами списка получить невозможно. Помните, что индексы начинаются с 0, поэтому максимальный допустимый индекс меньше, чем число элементов в списке. Вы можете проверить, как долго в списке используется свойство Count. Добавьте следующий код в конец программы:

Console.WriteLine($"The list has {names.Count} people in it");

Сохраните файл и еще раз введите dotnet run, чтобы просмотреть результаты.

Поиск по спискам и их сортировка

В наших примерах используются сравнительно небольшие списки. Но приложения часто создают списки с гораздо большим количеством элементов, иногда они исчисляются в тысячах. Чтобы найти элементы в таких больших коллекциях, необходимо выполнить поиск различных элементов по списку. Метод IndexOf выполняет поиск элемента и возвращает его индекс. Если элемент отсутствует в списке, IndexOf возвращает -1. Добавьте этот код в конец программы:

var index = names.IndexOf("Felipe");
if (index == -1)
{
    Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
    Console.WriteLine($"The name {names[index]} is at index {index}");
}

index = names.IndexOf("Not Found");
if (index == -1)
{
    Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
    Console.WriteLine($"The name {names[index]} is at index {index}");

}

Кроме того, можно сортировать элементы в списке. Метод Sort сортирует все элементы списка в обычном порядке (строки — в алфавитном). Добавьте этот код в конец программы:

names.Sort();
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

Сохраните файл и введите dotnet run, чтобы протестировать последнюю версию.

Прежде чем перейти к следующему разделу, переместим текущий код в отдельный метод. Это упростит начало работы с новым примером. Поместите весь написанный код в новый метод с именем WorkWithStrings(). Вызовите этот метод в начале кода программы. В результате ваш код должен выглядеть примерно следующим образом:

WorkWithStrings();

void WorkWithStrings()
{
    List<string> names = ["<name>", "Ana", "Felipe"];
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }

    Console.WriteLine();
    names.Add("Maria");
    names.Add("Bill");
    names.Remove("Ana");
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }

    Console.WriteLine($"My name is {names[0]}");
    Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

    Console.WriteLine($"The list has {names.Count} people in it");

    var index = names.IndexOf("Felipe");
    if (index == -1)
    {
        Console.WriteLine($"When an item is not found, IndexOf returns {index}");
    }
    else
    {
        Console.WriteLine($"The name {names[index]} is at index {index}");
    }

    index = names.IndexOf("Not Found");
    if (index == -1)
    {
        Console.WriteLine($"When an item is not found, IndexOf returns {index}");
    }
    else
    {
        Console.WriteLine($"The name {names[index]} is at index {index}");

    }

    names.Sort();
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }
}

Списки других типов

Вы уже использовали в списках тип string. Создадим List<T> с использованием другого типа. Сначала создадим набор чисел.

Добавьте следующий код в программу после вызова WorkWithStrings():

List<int> fibonacciNumbers = [1, 1];

Будет создан список целых чисел. Для первых двух целых чисел будет задано значение 1. Это два первых значения последовательности Фибоначчи. Каждое следующее число Фибоначчи — это сумма двух предыдущих чисел. Добавьте этот код:

var previous = fibonacciNumbers[fibonacciNumbers.Count - 1];
var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2];

fibonacciNumbers.Add(previous + previous2);

foreach (var item in fibonacciNumbers)
{
    Console.WriteLine(item);
}

Сохраните файл и введите dotnet run, чтобы просмотреть результаты.

Совет

Для задач этого раздела вы можете закомментировать код, который вызывает WorkWithStrings();. Просто поместите два / символа перед вызовом, как показано ниже: // WorkWithStrings();.

Задача

Попробуйте объединить некоторые идеи из этого и предыдущих занятий. Расширьте код с числами Фибоначчи, который вы создали. Попробуйте написать код для создания первых 20 чисел в последовательности. Подсказка: 20-е число Фибоначчи — 6765.

Выполнение задачи

Пример решения можно просмотреть в готовом примере кода на GitHub.

При каждой итерации цикла суммируются два последних целых числа в списке. Полученное значение добавляется в список. Цикл повторяется, пока в список не будут добавлены 20 элементов.

Поздравляем! Вы выполнили задачи в руководстве по спискам. Можете продолжить изучение дополнительных руководств в своей среде разработки.

Дополнительные сведения о работе с типом List см. в статье Коллекции и структуры данных. Также в нем описаны многие другие типы коллекций.