C# Индексатор массива объектов — почему так (см.)?

class Person
{
    public string Name { get; set; }
}
class People
{
    Person[] data;
    public People()
    {
        data = new Person[5];
    }
    // индексатор
    public Person this[int index]
    {
        get
        {
            return data[index];
        }
        set
        {
            data[index] = value;
        }
    }
}


spoiler
class Program
    {
    static void Main(string[] args)
    {
        People people = new People();
        people[0] = new Person { Name = "Tom" };
        people[1] = new Person { Name = "Bob" };
 
        Person tom = people[0];
        Console.WriteLine(tom?.Name);
 
        Console.ReadKey();
    }
}


Имею в виду:

set
{
     data[index] = value;
}


Т.е. data[index] - это у нас объект класса Person - и почему-то правильно (я проверил) именно так, а не, скажем, вот так:

set
{
     data[index].Name = value;
}


А что если там не один только Name будет, ещё поля ??..

Спасибо : )
  • Вопрос задан
  • 367 просмотров
Решения вопроса 1
lexxpavlov
@lexxpavlov
Программист, преподаватель
Т.е. data[index] - это у нас объект класса Person

Не совсем так, это не объект класса Person, а элемент с индексом index в массиве data.
Индексатор, как и обычные свойства, - это просто сахарный синтаксис для создания методов геттера и сеттера (например, поля).

Обычное свойство заменяется на методы GetProperty() и SetProperty(<type> value).
А индексатор заменяется на методы GetIndexator(int index) и SetIndexator(int index, <type> value).

В этих методах можно писать что угодно, в вашем первом варианте вы пишете код доступа к массиву data. Но тип аргументов (index и value) определяются типом индексатора, то есть, вы можете сделать вот так:
Person[] data;

public string this[int index]
{
    get
    {
        return data[index]?.Name;
    }
    set
    {
        if (data[index] == null) data[index] = new Person();
        data[index].Name = value;
    }
}

Или даже вот так:
Person[] data;

public Person this[string name]
{
    get
    {
        return data.FirstOrDefault(p => p.Name == name);
    }
    set
    {
        for (var index = 0; index < data.Length; index++)
        {
            if (person.Name == name)
            {
                data[index] = value;
                break;
            }
        }
    }
}


То есть, вы не можете сделать так, как вы написали:
set
{
     data[index].Name = value;
}

потому что типом value будет Person, а не string. (вряд ли, что у вас у свойства Name тоже тип Person, или у вас есть implicit приведение из Person в string).

А что если там не один только Name будет, ещё поля ??..

А если у вас там больше свойств, то будьте добры указать это в коде. Точно так же, как и если только один Name, в общем-то.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы