Переменные могут быть полями класса, объявляться в функциях или даже внутри циклов (например: for (int i=0; i<n; i++) { … } ). Чтобы различать их, вводится понятие «область видимости переменных».
В разных частях программы имена переменных могут повторяться, что может иногда приводить к ошибкам типа «конфликт областей видимости».
Рассмотрим эти ситуации на примерах
Область видимости, или контекст переменной — это часть кода, в пределах которого доступна данная переменная. В общем случае такая область определяется описанными ниже правилами:
1. Поле, также известное как переменная-член класса, находится в области видимости до тех пор, пока в этой области находится содержащий поле класс.
2. Локальная переменная находится в области видимости до тех пор, пока закрывающая фигурная скобка не укажет конец блока операторов или метода, в котором она объявлена.
3. Локальная переменная, объявленная в операторах цикла for, while или подобных им, видима в пределах тела цикла.
Конфликты областей видимости локальных переменных.
Использование в больших программах одних и тех же имен переменных в разных частях программы является обычной практикой. Это нормально до тех пор, пока области видимости этих переменных не перекрываются и находятся в совершенно разных частях программы, таким образом, исключая любую неоднозначность.
Однако следует иметь в виду, что локальные переменные с одним и тем же именем не могут быть объявлены дважды в одном и том же контексте, поэтому вы не сможете поступить так, как показано ниже:
int х = 20;
// какой-то код
int х = 30;
Рассмотрим следующий пример кода с локальной переменной k (оператор цикла for изучается дальше):
using System; namespace Область_видимости_переменных_1 { class Program { static void Main(string[] args) { for(int k = 0; k < 10; k++) { Console.Write(" {0}", k ); } // здесь k покидает область видимости Console.WriteLine(); // мы можем вновь объявить k for (int k = 0; k > -10; k--) { Console.Write(" {0}", k ); } // k снова покидает область видимости Console.ReadLine(); var r = k * k; // данный код не выполнится, // так как k не определена в текущем контексте } } }
Важно отметить, что переменная k объявляется в этом коде два раза в пределах одного и того же метода Main(). Это можно делать, поскольку переменные k объявляются в двух отдельных циклах, поэтому каждая из них локальна в пределах собственного цикла.
Рассмотрим другой пример:
using System; namespace Область_видимости_переменных_2 { public static int Main() { int k = 20; for (int n = 0; n < 10; n++) { int k = 30; // Ошибка в этой строке!!! Console.WriteLine (k + n); } return 0; } }
Если вы попытаетесь скомпилировать это, то получите следующее сообщение об ошибке:
Ошибка: Невозможно объявить локальную переменную с именем «k» в этой области видимости, т.к. она придаст другое значение «k», которая уже используется в области видимости «родительский или текущий» для обозначения чего-то другого.
Дело в том, что переменная k, которая определена перед началом цикла for, внутри цикла все еще находится в области видимости и не может из нее выйти до завершения метода Main().
Хотя вторая переменная k (недопустимая) объявлена в контексте цикла, этот контекст вложен в контекст метода Main(). Компилятор не может различить эти две переменных, поэтому не допустит объявления второй из них.
Конфликты областей видимости полей и локальных переменных. В некоторых случаях два идентификатора с одинаковыми именами (хотя и не совпадающими полностью уточненными именами) и одинаковой областью видимости можно различить, и тогда компилятор допускает объявление второй переменной. Причина в том, что C# делает принципиальное различие между переменными, объявленными на уровне типа (в примере — полями класса) и переменными, объявленными в методах (локальными переменными).
Рассмотрим третий пример:
using System; namespace Область_видимости_переменных_3 { class Program { int k = 20; public static void Main() { int k = 30; Console.WriteLine(k); return; } } }
Этот код компилируется, несмотря на то, что здесь в контексте метода Main() присутствуют две переменных с именем k: переменная k, определенная на уровне класса и существующая до тех пор, пока не будет уничтожен класс (когда завершится метод Main(), а вместе с ним и программа), и переменная k, определенная внутри Main().
В данном случае новая переменная с именем k, объявленная в методе Main(), игнорирует переменную уровня класса с тем же именем. Поэтому когда вы запустите этот код, на дисплее будет отображено число 30.
В языке C# локальные переменные широко используются именно из-за аппарата разграничения области видимости. Не экономьте без необходимости на локальных переменных, если они не занимают большой объем памяти.
Следующее интуитивно понятие языка программирования — Литералы.
NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.
![]() |
![]() |
![]() |
![]() |
«В данном случае новая переменная с именем k, объявленная в методе Main(), игнорирует переменную уровня класса с тем же именем. Поэтому когда вы запустите этот код, на дисплее будет отображено число 30.»
а почем так?
получается что в данном примере использовать переменную k на уровне класса невозможно? или с помощью Program.k?
Андрей! Переменную k использовать можно, если написать так, как Вы предполагаете (нужно только добавить static):
Будет напечатано: 20.
Имя класса здесь используется для понимания компилятором, какое k использовать.
листинги какие-то невзрачные( может быть жирный шрифт поможет или смена цвета фона\шрифта
Важно, что они работающие. Спасибо, подумаю.
В заголовках тем, строчка
Оставьте комментарий / —>Основы языка Си шарп<— , кликабельная ссылка открывает страницу " https://c-sharp.pro/?cat=2 ", а скорее всего планировалась " https://c-sharp.pro/?p=787 ".
П. С. спасибо за ваш труд. Я восхищаюсь людьми, которые делятся знаниями безвозмездно.
Максим! Это нормальная ссылка на рубрику.