Прежде всего, ваш тест на странность неверен.
Ответ на ваш вопрос состоит в том, чтобы опровергнуть предпосылку вашего вопроса. Это не имеет ничего общего с альфа-преобразованием.
И не имеет ничего общего с "лексическим ограничением", под которым, по-видимому, подразумевается нечто иное, чем мое понимание лексического определения объема. C # - это лексически ограниченный язык.
Теперь я хочу подчеркнуть, что недопустимо объявлять два локальных языка в C #, где один скрывает другой .Совершенно законно прятаться в других сферах;параметр типа может скрывать параметр внешнего типа (хотя делать это действительно, очень глупо; не делайте этого.) Поле может скрывать поле базового класса (хотя вы должны пометить скрытое поле как «новое», чтобы подчеркнуть этот факт.) Местный житель может скрыть метод.И так далее.
Но локальный может не скрывать другого локального, потому что (1) это создает фермы ошибок и (2) нарушает более общее правило об использовании простых имен.
Это правило об именах - вот интересное правило. Вы бы получили похожую ошибку, если бы сделали это:
class C
{
int n;
void M()
{
Console.WriteLine(n); // n means this.n
Func<double, double> f = n=>n; // n means the formal parameter
}
}
Ошибка, которую вы получаете, состоит в том, что вы нарушаете правило C #, которое простое имя должно иметь непротиворечивое значение во всей локальной области, в которой оно впервые используется.
Программы, где 'n' означает одно в одной строке, а что-то совершенно другое в следующей, сбивают с толку иподвержен ошибкам и поэтому недопустим.
Если вы хотите сделать это, тогда два значения 'n' должны быть в непересекающихся областях:
class C
{
int n;
void M()
{
{
Console.WriteLine(n); // n means this.n
}
Func<double, double> f = n=>n; // n means the formal parameter
}
}
Это было бы законно, потому что теперь два использования n находятся в непересекающихся областях.
Проблема не имеет ничего общего с альфа-преобразованием.C # выполняет альфа-преобразование очень хорошо, когда это необходимо.
И это , потому что C # имеет лексическую область видимости, что компилятор может определить, что вы нарушаете это правило. Этоне является доказательством того, что в C # отсутствует лексическая область видимости;это свидетельство того, что имеет лексическую область видимости.
Подробнее об этом правиле см. в моей статье на эту тему:
http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx