Deklarationsbereich für Blockebene in C #

7

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.

    
kemiller2002 02.07.2009, 14:10
quelle

5 Antworten

29

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 Semantik einer Identifier-Suche .)

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.

    
Eric Lippert 02.07.2009, 20:55
quelle
8

Ah - Sie haben keinen Durchfall, aber Sie können mit goto zu einem anderen markierten Fallblock springen. Daher müssen die Blöcke im selben Umfang sein.

    
NeedHack 02.07.2009 14:16
quelle
3

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.

    
Timothy Carter 02.07.2009 14:12
quelle
2

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.

    
John Rudy 02.07.2009 14:13
quelle
0

Sie könnten die Variable einfach außerhalb des Bereichs der switch-Anweisung deklarieren.

%Vor%     
Nate 02.07.2009 14:16
quelle