Почему компилятор C # допускает дублирование переменной во вложенной области видимости?

18

Исторически при разработке в .Net я не мог дублировать имя переменной во вложенной области видимости. Однако после недавнего обновления Visual Studio 2019 до версии 16.4.2 я заметил, что имена переменных могут дублироваться во вложенной области видимости.

Например:

var test = "hello";
Console.WriteLine(test);
var things = new []{"one", "two", "three"};
things.Select(test => // <- test is duplicated here, normally this breaks compilation
{
    Console.WriteLine(test);
    return test;
}).ToList();

// output:
// hello
// one
// two
// three

https://dotnetfiddle.net/h85BK4

Почему это вдруг разрешено?

Дополнительный вопрос: если это новая языковая «функция», есть ли способ настроить Visual Studio таким образом, чтобы он продолжал разрываться, когда переменная дублируется во вложенной области?

masterjeef
источник
2
я не думаю, что допускается дублирование переменной. он использует ту же testпеременную, так как тип данных одинаков. попробуйте объявить testпеременную как, int например. var test = 12345;Я думаю, вы должны получить ошибку компиляции. (Я не пробовал это)
LP13
1
@ LP13 Изменение типа, testкак предлагается, не имеет никакого эффекта. Вы можете попробовать это в Скрипке, связанной в вопросе.
Эми
1
Неважно, целевая структура не имеет значения. Новое поведение связано с языковой версией. Код компилируется на C # 8, он не компилируется на C # 7.3 (и ниже я предполагаю)
Emanuel Vintilă
6
Для этого есть проблема с GitHub . Веха установлена ​​на 16,5. @OrkhanAlikhanov вы нашли это быстрее :)
Павел Аниховский

Ответы:

1

Это новая функция в C # 8.0, локальные функции и лямбда-параметры могут скрывать внешние имена.

Себастьян 506563
источник
0

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

и в этом случае эта тестовая переменная является собственной переменной и не имеет связей с вышеуказанной тестовой переменной.

Что касается предотвращения этого, вы не можете сказать vs выдавать ошибку, когда она возникает, вам просто нужно вручную изменить имя переменной.

Бейли Драгосс
источник