Menu
Coddy logo textTech

Индексаторы (this[])

Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 37 из 70.

Индексаторы позволяют обращаться к элементам вашего класса, используя синтаксис квадратных скобок, подобно массивам. Вместо вызова метода, такого как collection.GetItem(0), вы можете написать более интуитивно понятное collection[0].

Вы определяете индексатор с помощью ключевого слова this с квадратными скобками:

public class Sentence
{
    private string[] words;
    
    public Sentence(string text)
    {
        words = text.Split(' ');
    }
    
    public string this[int index]
    {
        get { return words[index]; }
        set { words[index] = value; }
    }
}

Теперь вы можете обращаться к словам естественным образом:

Sentence s = new Sentence("Hello World");
Console.WriteLine(s[0]);  // Hello
s[1] = "C#";
Console.WriteLine(s[1]);  // C#

Индексаторы не ограничиваются целыми числами. Вы можете использовать любой тип в качестве параметра индекса, что делает их полезными для доступа, подобного словарю:

public string this[string key]
{
    get { return dictionary[key]; }
    set { dictionary[key] = value; }
}

Как и свойства, индексаторы могут быть только для чтения (если опустить setter) или содержать логику валидации в своих аксессорах. Они идеально подходят в тех случаях, когда ваш класс оборачивает коллекцию или когда использование квадратных скобок делает код более читаемым.

challenge icon

Задание

Легко

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

Вы организуете свой код в двух файлах:

  • Playlist.cs: Создайте класс Playlist в пространстве имен Music, который оборачивает внутреннюю коллекцию песен и обеспечивает доступ к ним подобно массиву через индексатор. Ваш плейлист должен иметь:
    • Закрытый массив строк для хранения названий песен
    • Конструктор, который принимает строку с названиями песен, разделенными запятыми, и разбивает ее во внутренний массив
    • Индексатор, использующий синтаксис this[int index], который позволяет как получать, так и изменять песни в определенной позиции
    • Свойство только для чтения Count, которое возвращает количество песен в плейлисте
    • Метод GetAllSongs(), который возвращает все песни, объединенные строкой " | "
  • Program.cs: В основном файле создайте плейлист из входных данных, а затем используйте индексатор для доступа к песням и их изменения. Продемонстрируйте как чтение песни по индексу, так и обновление песни в определенной позиции.

Вы получите три входных значения:

  • Список названий песен через запятую (например, Song A,Song B,Song C)
  • Индекс для извлечения (целое число)
  • Новое название песни для замены песни по этому же индексу

Выведите результат в следующем формате:

Total songs: {Count}
Song at index {index}: {song title}
After update: {GetAllSongs()}

Например, если входные данные: Rock Anthem,Jazz Vibes,Pop Hit, 1 и Blues Classic, результат должен быть:

Total songs: 3
Song at index 1: Jazz Vibes
After update: Rock Anthem | Blues Classic | Pop Hit

Обратите внимание, как индексатор позволяет вам обращаться к playlist[1], чтобы получить "Jazz Vibes", а затем присвоить playlist[1] = "Blues Classic" для обновления — это гораздо естественнее, чем вызов таких методов, как GetSongAt(1) или SetSongAt(1, "Blues Classic")!

Шпаргалка

Индексаторы позволяют вам обращаться к элементам вашего класса, используя синтаксис квадратных скобок, как в массивах (collection[0]), вместо вызова методов.

Определите индексатор, используя ключевое слово this с квадратными скобками:

public class Sentence
{
    private string[] words;
    
    public Sentence(string text)
    {
        words = text.Split(' ');
    }
    
    public string this[int index]
    {
        get { return words[index]; }
        set { words[index] = value; }
    }
}

Пример использования:

Sentence s = new Sentence("Hello World");
Console.WriteLine(s[0]);  // Hello
s[1] = "C#";
Console.WriteLine(s[1]);  // C#

Индексаторы могут использовать любой тип в качестве параметра индекса, а не только целые числа:

public string this[string key]
{
    get { return dictionary[key]; }
    set { dictionary[key] = value; }
}

Как и свойства, индексаторы могут быть только для чтения (если опустить setter) или содержать логику валидации в своих аксессорах.

Попробуйте сами

using System;
using Music;

class Program
{
    public static void Main(string[] args)
    {
        // Чтение входных данных
        string songList = Console.ReadLine();
        int index = Convert.ToInt32(Console.ReadLine());
        string newSong = Console.ReadLine();

        // TODO: Создайте объект Playlist из songList

        // TODO: Выведите общее количество песен, используя свойство Count

        // TODO: Выведите песню по заданному индексу, используя индексатор

        // TODO: Обновите песню по заданному индексу, используя индексатор

        // TODO: Выведите все песни после обновления, используя GetAllSongs()
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование