2013-05-22 7 views
63

Perché C# consentono questo:Perché C# consente dichiarazioni dopo un caso ma non prima di esso?

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

Ma non questo:

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

Qualsiasi altra lingua lo consente? – Vivasaayi

+50

perché vorresti farlo? – Jodrell

+12

Se è probabile che qualcuno scriva un codice come questo, è comunque una domanda interessante. Deve esserci qualche strana roba da scopare che si svolge dietro le quinte. –

risposta

119

Perché il vostro rientro è fuorviante, il primo codice è in realtà:

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

Quello è, x è dichiarato all'interno di un case dichiarazione (anche se dopo un break), dove è valida. Tuttavia, direttamente all'interno di un'istruzione switch non è valido: le sole affermazioni valide sono case e default.

Inoltre, const dichiarazioni vengono valutate al momento della compilazione, così x è definito anche se c'è una dichiarazione break prima.

Si noti tuttavia che il Mono compilatore C# non compilerà questo codice, si lamenta che “il nome di‘x’non esiste nell'ambito corrente” in modo Mono sembra attuare più controlli rispetto al compilatore .NET. Tuttavia, non riesco a trovare alcuna regola nello standard C# che proibisca questo uso della dichiarazione const quindi presumo che il compilatore .NET sia corretto e che il compilatore Mono sia sbagliato.

+2

Ma come mai si visualizza y, se effettivamente si rompe? – rtuner

+1

@rtuner Suppongo che la dichiarazione 'const' venga spostata all'inizio del metodo in fase di compilazione. – CodeCaster

+21

Le istruzioni @rtuner 'const' non vengono eseguite in fase di esecuzione, vengono sostituite al momento della compilazione. Prova a mettere un punto di rottura su di esso. – Jodrell

7

Poiché la specifica del linguaggio non permette un const direttamente nel vostro switch (unico caso e di default sono ammessi):

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

Dove:

expression: un tipo di espressione integrale o una stringa .
statement: Le istruzioni incorporate da eseguire se il controllo viene trasferito al caso o al valore predefinito.
jump-statement: Un'istruzione di salto che trasferisce il controllo fuori dal corpo del caso.
constant-expression: Il controllo viene trasferito a un caso specifico in base al valore di questa espressione.

Nel primo caso, const è parte della logica del caso. Il const funziona solo perché viene riscritto in compiletime e non in runtime.

1

... perché switch fa questo

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

e non questo

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 che, se questo è stato permesso, che si può trovare persone disposte a fare tutta la loro programmazione in là: -)

Problemi correlati