Почему область if и делегирует этот путь в С#

Вдохновленный этим question, я начал задаваться вопросом, почему следующие примеры являются незаконными в С#:

VoidFunction t = delegate { int i = 0; };

int i = 1;

и

{
   int i = 0;
}

int i = 1;

Мне просто интересно, знает ли кто то, почему именно язык был спроектирован таким образом? Разве это препятствует плохой практике программирования, и если да, почему бы просто не выпустить предупреждение?, по соображениям производительности (компиляция и при запуске) или в чем причина?

Ответ 1

Такое поведение описано в разделе 3 спецификации языка С#. Вот цитата из спецификации

Аналогично, любое выражение, которое происходит как тело анонимного функции в виде лямбда-выражение создает пространства декларации, которое содержит параметры анонимной функции. Это ошибка для двух членов локальное пространство декларации переменных переменных имеют одно и то же имя. Это ошибка для пространство с объявлением локальной переменной блока и вложенной локальной переменной пространство декларации для хранения элементов с тем же именем. Таким образом, в рамках вложенное пространство декларации не можно объявить локальную переменную или константа с тем же именем, что и локальная переменная или константа в охватывающее пространство декларации.

Я думаю, что более простой способ прочитать это - это то, что для объявления переменных (и многих других связанных с блоком функций) блок lambda/anonymous delegate обрабатывается не иначе, как обычный блок.

Что касается того, почему язык был спроектирован таким образом, спецификация явно не указана. Мое мнение - это простота. Если код рассматривается как еще один блок, он упрощает процедуры анализа кода. Вы можете сохранить все свои существующие процедуры для анализа блока для семантических ошибок и разрешения имен. Это особенно важно, когда вы рассматриваете переменный подъем. Lambdas в конечном итоге будет другой функцией, но они все еще имеют доступ ко всем переменным области видимости в точке объявления.

Ответ 2

Я думаю, что это делается так, чтобы внутренняя область могла обращаться к переменным, объявленным во внешней области. Если вам разрешено переписывать переменные, существующие во внешней области, может возникнуть путаница в отношении того, какое поведение было предназначено. Поэтому они, возможно, решили решить проблему, не допуская ее.

Ответ 3

Я думаю, что это так, чтобы разработчики не стреляли в ногу.