Какая разница, Часть вторая: область видимости, пространство деклараций, время жизни
Термин «scope» (область видимости) оказался одним из самых запутывающих слов во всём дизайне языков программирования. Люди, похоже, произвольно используют его для обозначения всего, что им удобно в каждый момент; чаще всего я вижу, как его путают с временем жизни и пространством деклараций. Как в «память освобождена, когда переменная выйдет из области видимости».
В неформальных обстоятельствах, конечно же, абсолютно допустимо применять «область видимости» для обозначения чего вам угодно до тех пор, пока значение понятно собеседникам. В более формальных условиях, типа в книге или в спецификации языка, вероятно лучше быть педантичным.
Разница между областью видимости и пространством деклараций в C# весьма тонка. Область видимости именованной сущности – это регион текста программы, в котором разрешено ссылаться на эту сущность по её неквалифицированному имени.
Тут есть некоторые тонкости. Импликация не работает «в обратную сторону» - из того, что вам можно использовать неквалифицированное имя сущности, не следует, что имя будет ссылаться именно на эту сущность. Области видимости могут перекрываться. Например, если у вас есть:
class C
{
int x;
void M()
{
int x;
}
}
то поле находится в области видимости во всём тексте тела C, включая весь M. Локальная переменная x находится в области видимости во всём теле M, так что их области видимости перекрываются. Когда вы говорите «x», то поле ли выбирается или переменная зависит от того, где вы это говорите.
В противоположность этому, пространство деклараций – это регион текста программы, в котором никаким двум сущностям нельзя иметь одинаковые имена. Например, в пределах текста тела C исключая тело M, вам нельзя поместить ничего другого по имени x. Как только вы получили поле по имени x, вы не можете завести другое поле, свойство, вложенный тип, или событие по имени x.
Благодаря перегрузке, у методов тут есть некоторая странность. Один из способов охарактеризовать пространства деклараций в контексте методов состоит в утверждении «набор всех перегруженных методов в классе, которые имеют одно и то же имя, составляет одну «сущность»». Другой способ охарактеризовать методы состоит в исправлении определения пространства деклараций так, чтобы в нём двум вещам нельзя было бы иметь одинаковые имена за исключением набора методов, которые все различаются сигнатурами. Короче, область видимости отвечает на вопрос «где я могу использовать это имя?», а пространство деклараций – на вопрос «где это имя уникально?»
Время жизни и область видимости часто путают из-за сильной связи между ними для локальных переменных. Самый лаконичный способ выразить эту связь – в утверждении, что содержимое локальной переменной гарантированно будет живым как минимум до тех пор, пока текущая «точка исполнения» находится в области видимости локальной переменной. «Как минимум», конечно же, подразумевает «или дольше»; захват локальной переменной, к примеру, продлевает время её жизни.