Почему компилятор 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 таким образом, чтобы он продолжал разрываться, когда переменная дублируется во вложенной области?


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, локальные функции и лямбда-параметры могут скрывать внешние имена.


0

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.