Вопрос по области видимости локальных переменных C # - PullRequest
1 голос
/ 11 октября 2010

Мне просто интересно, я думал, что у меня не может быть переменных с таким же именем:

int Test;
public void A(int Test)
{

}

Почему это компилируется? Я знаю, что могу использовать это ключевое слово, но мне кажется странным, что, поскольку метод находится в области видимости класса, он позволяет мне объявлять переменную с тем же именем.

Ответы [ 8 ]

11 голосов
/ 11 октября 2010

int Test; не переменная, а поле. Локальные переменные могут иметь то же имя, что и поля. Если вы ссылаетесь на имя, локальная переменная имеет предпочтение. Если вы хотите сослаться на поле, используйте this.

8 голосов
/ 11 октября 2010

Эти переменные имеют разные имена!

Имя первой переменной full действительно MyType.Test, а второй переменной (параметр функции) просто Test.

4 голосов
/ 11 октября 2010

Из спецификации языка C #, раздел 3.7 - Области применения

Область имени - это область текст программы, в пределах которой можно сослаться на сущность объявленный именем без уточнение имени. Области могут быть вложенным, и внутренняя область видимости может переопределить значение имени из внешняя сфера (это не так, Тем не менее, снять ограничение наложенный §3.3, который в пределах вложенного блокировать невозможно объявить локальная переменная с тем же именем, что и локальная переменная во вложенном блоке). Имя из внешней области видимости тогда говорят, что спрятаны в области текст программы покрыт внутренним область, и доступ к внешнему имени возможно только путем уточнения имени.

1 голос
/ 11 октября 2010

Со стороны разработчиков C # часто возникает путаница между областью действия, пространством объявлений и временем жизни .

Язык C # специально позволяет описать описанный вами случайсделать тело метода отличным от объявления пространства тела метода.Это учитывает такие случаи, как:

class Foo
{
   private string name;
   public Foo( string name )
   {
       this.name = name;
   }
}

, где выбор лучшего имени для параметра name потребует от разработчиков применения соглашений об именах (что некоторые в любом случае делают).Термин scope , относится к областям текста программы, где вы можете ссылаться на конструкцию по ее безусловному имени. Важно понимать, что области видимости могут перекрываться, что здесь имеет место.

1 голос
/ 11 октября 2010

Вы можете скрыть более широкие области видимости во многих случаях (но не так широко, как вы можете в некоторых других языках стиля C), и, конечно, может иметь поле и параметр с тем же именем (или поле и локальное).

С одной стороны, если мы не позволим области видимости скрывать более широкую область, часто используемые слова вскоре будут запрещены из-за более широкой области видимости.

Для другого мы можем ввести что-тов более широком масштабе вниз по линии, и даже из другой сборки.Скажем, у вас не было int Test; выше.Теперь представьте, чем это является в классе, производном от другого, и в этом кто-то добавляет public int Test;.Что должно быть сделано, чтобы справиться с этим.

Конечно, хорошей идеей является избегать таких конфликтов имен, и могут помочь соглашения (строчные буквы для локальных, строчные буквы для не приватных членовподчеркивание начала для частного использования имеет то преимущество, что вы жалуетесь на подчеркивание, не совместимое с CLR, если вы временно сделаете приватного участника публичным в эксперименте и забудете его отменить), но прямой его запрет будет невозможен.

1 голос
/ 11 октября 2010

Можно.Переменная-член (вне метода) должна называться this.Test в рамках самого метода.Внутри метода Test будет ссылаться на параметр.

1 голос
/ 11 октября 2010

Это позволит вам сделать это, поскольку вы не обращались к переменной Test в этом примере кода. Вы должны будете ссылаться на переменную класса Test как this.Test в методе A, чтобы устранить неоднозначность. В общем, вы не должны этого делать, это плохой стиль. Рекомендуемый стиль кодирования состоит в том, что переменные-члены должны начинаться с символа _, поэтому теперь ваш код будет выглядеть так:

int _Test;
public void A(int Test)
{
}
1 голос
/ 11 октября 2010

Вы можете, и это будет Тень , это поле Тест в вашем классе.По сути, переопределить переменную невозможно, только если переменная local с тем же именем уже удалена в текущей области видимости.Но в вашем случае один имеет область видимости класса, а другой - область метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...