Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Индексаторы в C#: делаем объекты доступными как массивы

Что такое индексатор

Индексатор (Indexer) — специальный член класса/структуры, позволяющий обращаться к экземпляру как к массиву: obj[index]. Объект ведёт себя как виртуальный массив.

Синтаксис

public ТипЭлемента this[ТипИндекса индекс]
{
    get { /* вернуть значение по индексу */ }
    set { /* установить значение по индексу */ }
}

Пример: индексатор по строке (имена)

public class IndexedNames
{
    private string[] _names = new string[10];
    public static int Size = 10;

    public IndexedNames()
    {
        for (int i = 0; i < Size; i++) _names[i] = "N.A.";
    }

    public string this[int index]
    {
        get
        {
            if (index >= 0 && index < Size) return _names[index];
            return ""; // или throw new IndexOutOfRangeException()
        }
        set
        {
            if (index >= 0 && index < Size) _names[index] = value;
        }
    }

    // Перегруженный индексатор по строке — поиск индекса по имени
    public int this[string name]
    {
        get
        {
            for (int i = 0; i < Size; i++)
                if (_names[i] == name) return i;
            return -1; // не найдено
        }
    }
}

// Использование
var names = new IndexedNames();
names[0] = "Zara";
names[1] = "Riz";
names[2] = "Nuha";

for (int i = 0; i < IndexedNames.Size; i++)
    Console.WriteLine(names[i]); // через int индексатор

Console.WriteLine(names["Nuha"]); // 2 — через string индексатор

Перегруженные индексаторы

Можно объявить несколько индексаторов с разными сигнатурами (тип/число параметров):

public class Matrix
{
    private double[,] _data;
    
    // Двумерный индексатор
    public double this[int row, int col]
    {
        get => _data[row, col];
        set => _data[row, col] = value;
    }
    
    // Индексатор по кортежу (C# 7+)
    public double this[(int Row, int Col) rc]
    {
        get => _data[rc.Row, rc.Col];
        set => _data[rc.Row, rc.Col] = value;
    }
}

Индексаторы в интерфейсах

public interface IRepository
{
    T this[int id] { get; set; }
}

public class UserRepository : IRepository
{
    private Dictionary _users = new();
    
    public User this[int id]
    {
        get => _users.TryGetValue(id, out var u) ? u : null;
        set => _users[id] = value;
    }
}

Свойства vs Индексаторы

ХарактеристикаСвойствоИндексатор
ИдентификацияПо имениПо сигнатуре параметров (this[])
ПараметрыНетОбязательно хотя бы один
СтатическиеМогут быть staticНе могут быть static
НазначениеДоступ к одному значению/состояниюДоступ к элементам коллекции/структуры
НаследованиеVirtual/overrideVirtual/override

Expression-bodied индексаторы (C# 7.0+)

public class BitVector
{
    private ulong _bits;
    
    public bool this[int index]
    {
        get => (_bits & (1UL << index)) != 0;
        set
        {
            if (value) _bits |= 1UL << index;
            else _bits &= ~(1UL << index);
        }
    }
}

Лучшие практики

Язык C

  1. C# Hello World — создание вашего первого C# приложения
  2. Понимание ключевых слов и идентификаторов C#: правила, списки и лучшие практики
  3. Мастерство C# переменных и примитивных типов данных: полное руководство
  4. Операторы C# — исчерпывающее руководство по операторам в C#
  5. Освоение побитовых и сдвиговых операторов в C#: полное руководство
  6. Основы ввода-вывода в C#: Console.WriteLine, ReadLine и форматирование
  7. Выражения, операторы и блоки в C#: подробное руководство с примерами
  8. Освоение комментариев в C#: виды, лучшие практики и XML-документация
  9. Освоение оператора switch в C#: синтаксис, примеры и лучшие практики
  10. Тернарный оператор в C#: краткое руководство по условным выражениям