Gibt es einen Grund, warum ich vermisse, dass ein Block innerhalb einer case-Anweisung nicht als Deklarationsraum auf Blockebene betrachtet wird?
Ich bekomme immer einen Fehler (Variable wurde bereits deklariert), wenn ich
versuche %Vor%aber ich kann
machen %Vor%Wenn C # erlaubt, durch statements zu fallen, würde das Sinn machen, aber das tut es nicht, und ich kann mir kein Szenario vorstellen, in dem Sie eine Variable in einer case-Anweisung deklarieren und sie außerhalb dieses Blocks verwenden können.
UPDATE: Diese Frage wurde als Inspiration für diesen Blogpost verwendet; Sehen Sie es für weitere Details.
Danke für die interessante Frage.
Es gibt eine Reihe von Verwirrungen und Falschaussagen in den verschiedenen anderen Antworten, von denen keine erklärt, warum dies illegal ist. Ich werde versuchen, endgültig zu sein.
Zuallererst, um genau zu sein, ist "Geltungsbereich" das falsche Wort, um das Problem zu beschreiben. Zufälligerweise schrieb ich letzte Woche einen Blogeintrag über diesen genauen Mißbrauch von "Scope"; das wird nach meiner Serie über Iteratorblöcke veröffentlicht, die im Juli laufen wird.
Der korrekte zu verwendende Begriff ist " Deklarationsbereich ". Ein Deklarationsbereich ist eine Code-Region, in der keine zwei verschiedenen Dinge mit demselben Namen deklariert werden dürfen . Das hier beschriebene Szenario ist symptomatisch für die Tatsache, dass ein switch -Abschnitt keinen Deklarationsbereich definiert, obwohl ein switch -Block dies tut. Seit den OPs zwei Deklarationen befinden sich im selben Deklarationsraum und haben denselben Namen, sie sind illegal.
(Ja, der Umschaltblock auch definiert einen Bereich, aber diese Tatsache ist für die Frage nicht relevant, da es sich um die Legalität einer Deklaration und nicht um
Eine vernünftige Frage ist: "Warum ist das nicht legal?" Eine vernünftige Antwort ist "gut, warum sollte es sein"? Sie können es auf zwei Arten haben. Entweder das ist legal:
%Vor%oder das ist legal:
%Vor%Aber Sie können es nicht beide Möglichkeiten haben. Die Entwickler von C # wählten den zweiten Weg als den natürlicheren Weg, dies zu tun.
Diese Entscheidung wurde am 7. Juli 1999, vor knapp zehn Jahren, getroffen. Die Kommentare in den Notizen von diesem Tag sind extrem kurz und geben einfach " Ein Switch-Case erzeugt keinen eigenen Deklarationsraum " und geben dann einen Beispielcode, der zeigt, was funktioniert und was nicht.
Um mehr darüber zu erfahren, was an diesem Tag in den Köpfen der Designer war, müsste ich viele Leute darüber aufklären, was sie vor zehn Jahren dachten - und sie über etwas belasten, was letztlich ein unbedeutendes Thema ist; Ich werde das nicht tun.
Kurz gesagt, es gibt keinen besonders zwingenden Grund, sich für die eine oder andere Art zu entscheiden; beide haben Vorteile. Das Sprachdesign-Team wählte einen Weg, weil sie einen auswählen mussten; der, den sie ausgewählt haben, erscheint mir vernünftig.
Sie könnten auch tun:
%Vor%Im Wesentlichen erstellen die geschweiften Klammern den lexikalischen Geltungsbereich, also wird ohne die geschweiften Klammern einige Variablen zweimal in die Symboltabelle geladen. Ich glaube, dass diese Wahl wahrscheinlich einfach getroffen wird, um Verwirrung zu vermeiden und möglicherweise zu vermeiden, dass die Erstellung der Symboltabelle komplexer wird.
Da Fälle keine Blöcke sind, gibt es keine geschweiften Klammern, die den Bereich angeben. Fälle sind, aus Mangel an einem besseren Wort, wie Etiketten.
Sie sollten die Variable besser außerhalb der switch()
-Anweisung deklarieren und danach verwenden. In diesem Szenario ist es natürlich nicht möglich, das Schlüsselwort var
zu verwenden, da der Compiler den zu initialisierenden Typ nicht kennt.
Tags und Links c# language-design switch-statement