Т.е. 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, в общем-то.