Невозможно использовать одно и то же имя переменной в методе - PullRequest
3 голосов
/ 25 июня 2011

Почему я не могу использовать одно и то же имя переменной, например index в методе?

Почему компилятор не может видеть различное, когда я ясно вижу?

Пример:

private void Foo()
{
    for (int index = 0; index < 10; index++) // "first"-index
    {
         // I'm in no doubt, use "first"-index here 
         // (and only within the scope of the for loop)
    }
    int index = 0; // "second"-index
    // I'm in no doubt, use "second"-index here 
    // (and below)
}

Это потому, что распределение производится во время компиляции? Но почему же компилятор не может просто вызвать «первый» -индекс для index_1 и «второй» -индекс для index_2?

Если у меня есть

    private void Foo()
    {
        for (int index = 0; index < 10; index++)
        {
        }
        // the runtime don't know index here
    }

Если среда выполнения не знает об индексе ниже цикла for, почему у нас не может быть другой переменной с таким именем?

Ответы [ 3 ]

6 голосов
/ 25 июня 2011

Пространство объявления этих переменных перекрывается, даже если область действия этого не делает.Посмотрите блог Эрика Липперта на эту тему:

Простые имена не так просты

Цель всех этих правил состоит в том, чтобы предотвратить класс ошибок вчто читатель / сопровождающий кода обманут, полагая, что он ссылается на одну сущность с простым именем, но фактически случайно ссылается на другую сущность целиком.Эти правила, в частности, предназначены для предотвращения неприятных сюрпризов при выполнении того, что должно быть безопасным рефакторингом.

В чем разница, часть вторая: область действия - пространство декларации против срока службы

Пространство объявления, напротив, представляет собой область текста программы, в которой двум объектам не разрешено иметь одно и то же имя.

Пространство объявления переменной больше, чемего сфера охвата, чтобы предотвратить эти вводящие в заблуждение ситуации.

6 голосов
/ 25 июня 2011

CodeInChaos в основном правильно, и в связанной статье объясняются правила, которые вы нарушаете.

Вы спрашиваете, почему компилятор не видит разницу, но вы можете.Странный вопрос: очевидно, компилятор может увидеть разницу.Если компилятор не может определить разницу между двумя значениями «index», тогда как он может правильно выдать ошибку ?!Ошибка в том, что есть две вещи, которые означают что-то другое, но имеют одно и то же имя, и поэтому, конечно, компилятор знает, что они разные.Это точно , потому что компилятор знает, что два значения «index» различны, что позволяет ему правильно выдавать ошибку.

Двигаемся дальше.

Наличие двух локальных переменных, которые означают разные вещи, является плохой практикой, приводящей к ошибкам, и поэтому существуют правила, которые предотвращают это.Если вы действительно хотите это сделать, вы можете, но , вам необходимо убедиться, что их области объявлений не перекрываются .Вы можете сделать это, введя дополнительные фигурные скобки:

{
    {
        int index; 
        // blah blah blah
    }  
    {
        int index;
        // blah blah blah
    }
}

Потому что теперь нет пробела, в котором "index" одновременно объявляется и означает две разные вещи.(Очевидно, что самое внешнее локальное пространство объявлений - это пространство, в котором «индекс» означает две разные вещи, но индекс не объявлен во внешнем пространстве объявлений.)

"for" и "foreach"Циклы обрабатываются так, как будто они имеют невидимые скобки вокруг всего этого, поэтому это законно:

{
    for(int index = 0; index <= 10; ++index) {...}
    for(int index = 0; index <= 10; ++index) {...}
}

Компилятор делает вид, что вы на самом деле написали

{
    {
        int index = 0; 
        while(index <= 10) { ... }
    }
    {
        int index = 0; 
        while(index <= 10) { ... }
    }
}

Итак, еще раз, "невидимый"фигурные скобки хранят два объявления локальных переменных в текстовом формате.

0 голосов
/ 25 июня 2011

Первый индекс не определен в рамках цикла for, поэтому он не может быть повторно объявлен вне цикла for.Однако внутри цикла for есть единственное место, к которому можно получить доступ к первому индексу, из-за того, как работает компилятор.

Просто переименуйте индекс вне цикла в index2.

Напомним,оба индекса находятся в одной и той же области, один из них доступен в другой области.

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