В первую очередь, позвольте мне сказать, что я никогда не использовал C# прежде, и я не знаю об этом очень.
Я изучал для своего экзамена "Языков программирования" с "Понятием Sebesta Языков программирования 9-го редактора" книга. После того, как я прочитал следующую выборку из "Порядка объявления объема (на 246-й странице)", я стал немного озадаченным:
"... Например, в C99, C++, Java объем всех локальных переменных от их объявлений до концов блоков, в которых появляются те объявления. Однако в C# объемом любой переменной, объявленной в блоке, является целый блок, независимо от положения объявления в блоке, пока это не находится во вложенном блоке. То же верно для методов. Обратите внимание, что C# все еще требует, чтобы все переменные были объявлены, прежде чем они будут использоваться. Поэтому, хотя объем переменной расширяется от объявления до вершины блока или подпрограмм, в которых появляется то объявление, переменная все еще не может использоваться выше ее объявления"
Почему разработчики C# принимали такое решение? Есть ли какая-либо определенная причина/преимущество такого необычного решения?
Посмотрите сообщения Эрика Липперта о декларативных пространствах, в которых приводится дополнительная информация об этих правилах.
Обычно я цитирую наиболее значимый фрагмент при ссылках на сообщения блога, но я думаю, что эти сообщения действительно дают лучший ответ, если читать их все вместе.
Надеюсь, он заглянет сюда и даст хорошее резюме.
Ответ Эрика Липперта на этот связанный вопрос может помочь.
Как ранее сказал Энтони Пеграм, C # применяет это правило, потому что бывают случаи, когда изменение порядка кода может вызвать небольшие ошибки, приводящие к путанице.
Одним из примеров преимущества уменьшения путаницы является то, что если у вас есть вложенный блок над объявлением переменной, то объявление переменной будет действовать и не позволит вложенному блоку объявить переменную с тем же именем.
Это не так уж и странно. Что касается переменных, он обеспечивает уникальное именование лучше, чем Java / C ++.
Это не позволяет вам делать что-то вроде
void Blah()
{
for (int i = 0; i < 10; i++)
{
// do something
}
int i = 42;
}
Причина в том, что это создает возможность для тонких ошибок, если вам нужно перемещать код, например. Если вам нужно i
перед циклом, то теперь ваш цикл сломан.
Из C# 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
}
}
Правила определения области видимости для локальных переменных разработаны для того, чтобы гарантировать, что значение имени, используемого в контексте выражения, всегда одинаково в пределах блока. Если бы область видимости локальной переменной распространялась только от ее объявления до конца блока, то в приведенном выше примере первое присваивание присваивалось бы переменной экземпляра, а второе - локальной переменной, что могло бы привести к ошибкам компиляции, если бы утверждения блока впоследствии были переставлены местами.