Вдохновленный этим вопрос, я начал задаваться вопросом, почему все следующие примеры недопустимы в C#:
VoidFunction t = delegate { int i = 0; };
int i = 1;
а также
{
int i = 0;
}
int i = 1;
Мне просто интересно, знал ли кто-нибудь точную причину, по которой язык был разработан таким образом? Для того, чтобы воспрепятствовать плохой практике программирования, и если да, то почему бы просто не выдать предупреждение? По причинам производительности (компиляция и при запуске) или в чем причина?





Это поведение описано в разделе 3 спецификации языка C#. Вот цитата из спецификации
Similarly, any expression that occurs as the body of an anonymous function in the form of a lambda-expression creates a declaration space which contains the parameters of the anonymous function. It is an error for two members of a local variable declaration space to have the same name. It is an error for the local variable declaration space of a block and a nested local variable declaration space to contain elements with the same name. Thus, within a nested declaration space it is not possible to declare a local variable or constant with the same name as a local variable or constant in an enclosing declaration space.
Я думаю, что более простой способ прочитать это состоит в том, что для целей объявления переменных (и многих других функций, связанных с блоками) блок лямбда / анонимного делегата обрабатывается не иначе, чем обычный блок.
Что касается того, почему язык был разработан таким образом, в спецификации явно не говорится. Мое мнение - простота. Если код рассматривается как просто еще один блок, это упрощает выполнение процедур анализа кода. Вы можете сохранить все свои существующие подпрограммы для анализа блока на предмет семантических ошибок и разрешения имен. Это особенно важно, когда вы думаете о переменном подъеме. Lambdas в конечном итоге будет другой функцией, но у них по-прежнему будет доступ ко всем переменным в области видимости в точке объявления.
@Anders, Да но в этом случае есть обходной путь. Доставка - это постоянное давление, и когда вы сталкиваетесь с выбором между большим рабочим элементом, чтобы получить небольшую часть функциональности, или мелким элементом, который делает отсутствие функциональности явным и может быть отменен позже, мелкий рабочий элемент обычно побеждает.
Я не понимаю, как это может быть очень сложно реализовать, по крайней мере, в случае if. Просто используйте стек и покончите с этим. Он сильно пахнет либо ошибкой, либо измерением, чтобы люди не стреляли себе в ногу, что потребовало от него некоторых полезных функций.
Я думаю, что это сделано таким образом, чтобы внутренняя область видимости могла получить доступ к переменным, объявленным во внешней области. Если вам разрешили перезаписывать переменные, существующие во внешней области видимости, может возникнуть путаница в отношении предполагаемого поведения. Поэтому они, возможно, решили решить проблему, предотвратив ее возникновение.
Вы не перезаписываете. Объявление во внешней области видимости идет после внутренней области.
Я думаю, что таким образом разработчики не могут прострелить себе ногу.
У скольких разработчиков есть оружие? Может, им стоит попрактиковаться в стрельбе ... может сэкономить несколько футов.
Похоже, что проблема в том, что они не делают различий между областью действия до и после отклонения. Это, вероятно, немного упрощает работу поставщика компилятора за счет обременения программиста.