Ich habe kürzlich einen Code geschrieben, in dem ich einen Variablennamen unbeabsichtigt als Parameter einer Aktion wiederverwendet habe, die in einer Funktion deklariert wurde, die bereits eine gleichnamige Variable enthält. Zum Beispiel:
var x = 1;
Action<int> myAction = (x) => { Console.WriteLine(x); };
Als ich die Duplizierung entdeckte, war ich überrascht zu sehen, dass der Code perfekt kompiliert und ausgeführt wurde. Dies ist kein Verhalten, das ich aufgrund meiner Kenntnisse über den Umfang in C # erwarten würde. Einige schnelle googeln drehte SO Fragen auf, die diesen ähnlichen Code beschweren sich einen Fehler, wie zum Beispiel produzieren Lambda Scope Klärung . (Ich habe diesen Beispielcode in meine IDE eingefügt, um zu prüfen, ob er ausgeführt wird, um sicherzugehen, dass er einwandfrei ausgeführt wird.) Wenn ich in Visual Studio das Dialogfeld "Umbenennen" aufrufe, wird der erste x
als Namenskonflikt hervorgehoben.
Warum funktioniert dieser Code? Ich verwende C # 8 mit Visual Studio 2019.
x
Parameter dieser Methode aus dem Bereich verschoben. Ein Beispiel finden Sie unter sharplab .Antworten:
Sie haben Ihre eigene Frage beantwortet! Das liegt daran, dass Sie C # 8 verwenden.
Die Regel von C # 1 bis 7 lautete: Ein einfacher Name kann nicht verwendet werden, um zwei verschiedene Dinge im selben lokalen Bereich zu bedeuten. (Die eigentliche Regel war etwas komplexer als diese, beschreibt jedoch, wie langwierig sie ist. Einzelheiten finden Sie in der C # -Spezifikation.)
Die Absicht dieser Regel war es, die Art von Situation zu verhindern, von der Sie in Ihrem Beispiel sprechen, in der es sehr leicht wird, über die Bedeutung des Lokalen verwirrt zu werden. Diese Regel wurde insbesondere entwickelt, um Verwirrungen wie:
Und jetzt haben wir eine Situation, in der im Körper von
M
,x
sowohlthis.x
als auch lokal bedeutetx
.Obwohl gut gemeint, gab es eine Reihe von Problemen mit dieser Regel:
Ich bemühte mich beim Umschreiben von Roslyn, dies zu klären. Ich habe einige neue Fehlermeldungen hinzugefügt und die alten konsistent gemacht, um festzustellen, wo der Fehler gemeldet wurde. Dieser Aufwand war jedoch zu gering, zu spät.
Das C # -Team entschied für C # 8, dass die gesamte Regel mehr Verwirrung stiftete als verhinderte, und die Regel wurde aus der Sprache entfernt. (Vielen Dank an Jonathon Chase für die Feststellung, wann der Ruhestand eingetreten ist.)
Wenn Sie daran interessiert sind, die Geschichte dieses Problems zu erfahren und zu erfahren, wie ich versucht habe, es zu beheben, lesen Sie die folgenden Artikel, die ich darüber geschrieben habe:
https://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
https://ericlippert.com/2009/11/05/simple-names-are-not-so-simple-part-two/
https://ericlippert.com/2014/09/25/confusing-errors-for-a-confusing-feature-part-one/
https://ericlippert.com/2014/09/29/confusing-errors-for-a-confusing-feature-part-two/
https://ericlippert.com/2014/10/03/confusing-errors-for-a-confusing-feature-part-three/
Am Ende des dritten Teils stellte ich fest, dass es auch eine Wechselwirkung zwischen dieser Funktion und der Funktion "Farbe Farbe" gab - dh der Funktion, die Folgendes ermöglicht:
Hier haben wir den einfachen Namen verwendet
Color
, um sowohl aufthis.Color
den aufgezählten Typ als auch auf den aufgezählten Typ zu verweisenColor
. Nach einer strengen Lektüre der Spezifikation sollte dies ein Fehler sein, aber in diesem Fall war die Spezifikation falsch und die Absicht war, dies zuzulassen, da dieser Code eindeutig ist und es ärgerlich wäre, den Entwickler dazu zu bringen, ihn zu ändern.Ich habe diesen Artikel nie geschrieben, in dem all die seltsamen Wechselwirkungen zwischen diesen beiden Regeln beschrieben werden, und es wäre ein bisschen sinnlos, dies jetzt zu tun!
quelle