2013-05-22 4 views
63

Warum erlaubt C# diese:Warum erlaubt C# Aussagen nach einem Fall, aber nicht davor?

var s = "Nice"; 
switch (s) 
{ 
    case "HI": 
     break; 
    const string x = "Nice"; 
    case x: 
     Console.Write("Y"); 
     break; 
} 

Aber nicht diese:

var s = "Nice"; 
switch (s) 
{ 
    const string x = "Nice"; 
    case x: 
     Console.Write("Y"); 
     break; 
} 
+8

Jede andere Sprache erlaubt es? – Vivasaayi

+50

Warum möchten Sie beides tun? – Jodrell

+12

Ob es wahrscheinlich ist, dass jemand Code wie diesen schreiben würde, ist immer noch eine interessante Frage. Es muss hinter den Kulissen seltsame Scoping-Sachen geben. –

Antwort

119

Weil Ihre Einbuchtung irreführend, tatsächlich der erste Code:

var s = "Nice"; 
switch (s) 
{ 
    case "HI": 
     break; 
     const string x = "Nice"; 
    case x: 
     Console.Write("Y"); 
     break; 
} 

That ist, x ist in einemdeklariertAussage (obwohl nach einem break), wo es gültig ist. Direkt in einer switch-Anweisung ist es jedoch ungültig - die einzigen gültigen Anweisungen sind case und default.

, Ferner const Erklärungen ausgewertet werden bei der Kompilierung, so x definiert ist, obwohl eine vor break Anweisung gibt.

weist jedoch darauf hin, dass die Mono C# Compiler wird diesen Code nicht kompiliert, klagt er, dass „der Name‚x‘existiert nicht im aktuellen Bereich“, so Mono mehr Kontrollen zu implementieren als der .NET-Compiler scheint. Allerdings kann ich im C# -Standard keine Regeln finden, die diese Verwendung der const-Deklaration verbieten, also nehme ich an, dass der .NET-Compiler richtig ist und der Mono-Compiler falsch ist.

+2

Aber wie sieht es aus, wenn es tatsächlich bricht? – rtuner

+1

@rtuner Ich denke, weil die 'const'-Deklaration zum Kompilierungszeitpunkt an den Anfang der Methode verschoben wird. – CodeCaster

+21

@rtuner 'const'-Anweisungen werden zur Laufzeit nicht ausgeführt, sie werden zur Kompilierzeit ersetzt. Versuchen Sie es und setzen Sie einen Unterbrechungspunkt darauf. – Jodrell

7

Da die Sprachspezifikation eine const direkt in Ihrem Switch nicht zulässt (nur Fall und Verzug sind erlaubt):

switch (expression) 
{ 
    case constant-expression: 
     statement 
     jump-statement 
    [default: 
     statement 
     jump-statement] 
} 

Wo:

expression: Integraler oder String-Ausdruck des Typs .
statement: Die eingebettete (n) Anweisung (en), die ausgeführt werden soll, wenn die Kontrolle an den Fall oder den Standard übergeben wird.
jump-statement: Eine Sprunganweisung, die die Steuerung aus dem Fallkörper überträgt.
constant-expression: Die Steuerung wird gemäß dem Wert dieses Ausdrucks in einen bestimmten Fall übertragen.

Im ersten Fall ist das const Teil Ihrer Falllogik. Das const-Testament funktioniert nur, weil es zur Kompilierungszeit und nicht zur Laufzeit neu geschrieben wird.

1

... weil switch erledigt diese

jump_to_the_label_matchig(s) 
{ 
    label1: 
     ... 
     done_quit_this; 
    label2: 
     ... 
     done_quit_this; 
    d'oh: 
     ... 
     done_quit_this; 
} 

und nicht diese

now_jump_to_the_label_matchig(s) 
{ 

    le'mme_wander_around_doing_things_that_could_have_been_done_before_me; 

    label1: 
     ... 
     done_quit_this; 
    label2: 
     ... 

I Betcha, dass, wenn das erlaubt wurde, Sie bereit Leute finden würden alle dort ihre Programmierung zu tun: -)

Verwandte Themen