Pourquoi le compilateur C # autorise-t-il une variable dupliquée dans une portée imbriquée?

18

Historiquement, lors du développement en .Net, je ne pouvais pas dupliquer le nom de la variable dans la portée imbriquée. Cependant, après avoir récemment mis à jour Visual Studio 2019 vers la version 16.4.2, j'ai remarqué que les noms de variables peuvent être dupliqués dans une portée imbriquée.

Par exemple:

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

Pourquoi est-ce soudainement autorisé?

Question de suivi: s'il s'agit d'une nouvelle "fonctionnalité" de langue, existe-t-il un moyen de configurer Visual Studio pour qu'il continue à se rompre lorsqu'une variable est dupliquée dans la portée imbriquée?

masterjeef
la source
2
je ne pense pas que cela autorise la variable en double. il utilise la même testvariable car le type de données est le même. essayez de déclarer la testvariable comme int par exemple. var test = 12345;je pense que vous devriez obtenir une erreur de compilation. (Je ne l'ai pas essayé)
LP13
1
@ LP13 Changer le type de testcomme suggéré n'a aucun effet. Vous pouvez l'essayer dans le violon lié dans la question.
Amy
1
Peu importe, le cadre cible n'est pas pertinent. Le nouveau comportement est dû à la version linguistique. Le code compile sur C # 8, il ne compile pas sur C # 7.3 (et ci-dessous je suppose)
Emanuel Vintilă
6
Il y a un problème avec GitHub pour cela. Le jalon est défini sur 16,5. @OrkhanAlikhanov vous l'avez trouvé plus rapidement :)
Pavel Anikhouski

Réponses:

1

Il s'agit d'une nouvelle fonctionnalité de C # 8.0, la fonction locale et les paramètres lambda peuvent masquer les noms externes.

Sebastian 506563
la source
0

ma conjecture est que la fonction de sélection est compilée comme statique car elle n'a pas de connexions avec le corps de la méthode hôte. il imprime et renvoie simplement l'article en question. cela ne nécessite aucun accès à la méthode et en tant que tel, il peut, pour des raisons d'optimisation, être déplacé hors du corps de la méthode et placé seul dans la portée globale.

et dans ce cas, cette variable de test est sa propre variable et n'a aucun lien avec la variable de test ci-dessus.

quant à empêcher cela, vous ne pouvez pas dire à vs de lancer une erreur quand elle se produit, vous aurez juste à changer manuellement le nom de la variable.

Bailey Drahoss
la source