Резюме для программиста
Погуглил и быстро нашел ответ:
1. Официальный ответ:
Да я уже находил объяснения где-то тут в комментах
Что нового в C# 8? / Хабр (habr.com)
в которых отсылали сюда
E.W. Dijkstra Archive: Why numbering should start at zero (EWD 831) (utexas.edu)
Проблема в том, что у них оператор концевого индекса ^ ведёт себя по разному внутри других операторов.
Вот такая конструкция кидает исключение
[^0]
а вот такая не кидает.
[0..^0]
Ну это следствие разных принципов работы. Ведь у нас
для оператора [] оператор концевого индекса ^0 равен Length
а для оператора [..] оператор концевого индекса ^0 равен Length-1
А запись ^1 означает Length-2.
Вам ничего не кажется странным? Пишем 1, а это на самом деле 2. Но только в этом месте в этой нотации - в концевом индексе диапазонного оператора.
И вот таких мелочей, которые надо всегда держать в голове, всё больше и больше.
Я не знаю, кому там удобнее вычислять срезы с массивов такой отличающейся нотацией, но cognitive load у меня явно повышается. Мне было неудобно и с 0 отсчитывать индекс, и от конца всегда явно единицу отнимать или писать невключающий интервал через знак < вместо <=. Но ок, раз так решили и все смирились - я тоже смирился. Но почему теперь когда с конца берём индекс, то теперь всё с ног на голову переворачиваем?