Вопрос о переменном диапазоне С# и других языках
Прежде всего, позвольте мне сказать, что я никогда раньше не использовал С#, и я не очень об этом знаю.
Я учился на своем экзамене "Языки программирования" с книгой Sebesta "Концепции языков программирования 9-го издания". После того, как я прочитал следующую выдержку из "Расположения декларации области (на 246-й странице)", я немного озадачился:
"... Например, в C99, С++, Java область всех локальных переменных от их объявлений до концов блоков, в которых появляются эти объявления. Однако в С# область действия любой переменной объявленный в блоке, является целым блоком, независимо от позиции объявления в блоке, если он не находится во вложенном блоке. То же самое верно для методов. Обратите внимание, что С# по-прежнему требует что все переменные должны быть объявлены до их использования. Поэтому, хотя область действия переменной простирается от объявления до вершины блока или подпрограмм, в которых это объявление появляется, переменная по-прежнему не может использоваться над ее объявлением
Почему дизайнеры С# приняли такое решение? Есть ли какая-то конкретная причина/преимущество для такого необычного решения?
Ответы
Ответ 1
Взгляните на сообщения Эрика Липперта о пространствах объявлений, в которых приведены дополнительные сведения об этих правилах.
Обычно я цитирую наиболее релевантный бит при связывании с сообщениями в блоге, но я думаю, что они действительно дают лучший ответ, когда все читаются вместе.
Надеюсь, он выйдет и даст хорошее резюме.
Ответ 2
Это не позволяет вам делать что-то вроде
void Blah()
{
for (int i = 0; i < 10; i++)
{
// do something
}
int i = 42;
}
Причина в том, что он вводит возможность для тонких ошибок, если вам нужно, например, перемещать код. Если вам нужен i
перед вашим циклом, теперь ваш цикл сломан.
Ответ 3
Одним из примеров преимущества путаницы является то, что если у вас есть вложенный блок над объявлением переменной, объявление переменной будет действовать и не позволит вложенному блоку объявить переменную с тем же именем.
Ответ 4
Из С# Spec
class A
{
int i = 0;
void F() {
i = 1; // Error, use precedes declaration
int i;
i = 2;
}
void G() {
int j = (j = 1); // Valid
}
void H() {
int a = 1, b = ++a; // Valid
}
}
Правила определения местоположения для локальных переменных призваны гарантировать, что значение имени, используемого в контексте выражения, всегда остается неизменным внутри блока. Если область локальной переменной должна была распространяться только от ее объявления до конца блока, то в приведенном выше примере первое присваивание присваивает переменной экземпляра, а второе назначение присваивает локальной переменной, что может привести к ошибки компиляции, если последующие инструкции блока были перегруппированы.
Ответ 5
Это не так странно. Что касается переменных, они обеспечивают уникальное наименование лучше, чем Java/С++.
Ответ 6
Ответ Эрика Липперта на этот связанный вопрос мог бы помочь.
Как ранее говорил Энтони Пегэм, С# применяет это правило, потому что бывают случаи, когда переупорядочение кода может вызвать тонкие ошибки, что приводит к путанице.