2012-12-05 16 views
16

This question mi ha ricordato di un vecchio domanda senza risposta nella mia mente su interruttore:strano portata variabile in istruzione switch

int personType = 1; 
    switch (personType) 
    { 
     case 1: 
      Employee emp = new Employee(); 
      emp.ExperienceInfo(); 
      break; 
     case 2: 
      Employee emp = new Employee(); 
      //Error: A local variable named 'emp' is already defined in this scope 
      emp.ManagementInfo(); 
      break; 
     case 3: 
      Student st = new Student(); 
      st.EducationInfo(); 
      break; 
     default: 
      MessageBox.Show("Not valid ..."); 
    } 

il motivo per cui è emp riconosciuto nel 'caso 2'? in C++ (se non sbaglio) potremmo utilizzare più casi insieme, ma in C# che è impossibile e dovremmo chiudere case 1 con pausa in modo che il seguente codice sembra giusto in C++ e sbagliato in C#:

case 1: 
case 2: 
    SomeMethodUsedByBothStates(); 

Quando non possiamo avere un comportamento del genere quindi perché dovremmo essere in grado di dichiarare emp in case 1 e vederlo in case 2? Se mai due casi accadono insieme, quindi perché l'oggetto dovrebbe essere visto in entrambi?

risposta

34

Casi non creano portata in C++ o in C#. Tutte le variabili dichiarate all'interno di un caso sono nello stesso ambito, quello dell'istruzione switch. È necessario utilizzare le parentesi se si desidera che tali variabili siano locale per alcuni casi specifici:

switch (personType) 
{ 
    case 1: { 
     Employee emp = new Employee(); 
     emp.ExperienceInfo(); 
     break; 
    } 
    case 2: { 
     Employee emp = new Employee(); 
     // No longer an error; now 'emp' is local to this case. 
     emp.ManagementInfo(); 
     break; 
    } 
    case 3: { 
     Student st = new Student(); 
     st.EducationInfo(); 
     break; 
    } 
    ... 
} 
+4

+1. Ho imparato qualcosa di nuovo proprio ora :) grazie –

5

Il secondo codice che avete mostrato è perfettamente bene in C#, assumendo il caso 2 ha avuto un break o return:

case 1: 
    // no code here... 
case 2: 
    SomeMethodUsedByBothStates(); 
    break; 

casi vuoti sono autorizzati a cadere.
Che cosa è non consentito è quello di avere il codice in un caso-ramo che cade attraverso. Così, il seguente sarebbe valida:

case 1: 
    SomeMethodUsedOnlyByCase1(); 
    // no break here... 
case 2: 
    SomeMethodUsedByBothStates(); 
    break; 

La questione circa il campo di applicazione è un altro. Fondamentalmente, l'ambito è l'istruzione switch stessa, non un caso-branch.

Per rendere il vostro esempio di compilazione, semplicemente dare i casi di rami ambiti di loro con l'aggiunta di parentesi graffe:

int personType = 1; 
switch (personType) 
{ 
    case 1: 
    { 
     Employee emp = new Employee(); 
     emp.ExperienceInfo(); 
     break; 
    } 
    case 2: 
    { 
     Employee emp = new Employee(); 
     emp.ManagementInfo(); 
     break; 
    } 
    case 3: 
    { 
     Student st = new Student(); 
     st.EducationInfo(); 
     break; 
    } 
    default: 
     MessageBox.Show("Not valid ..."); 
} 
2

Quando si dichiara variabili all'interno di una custodia, utilizzare le parentesi per spesification.

int personType = 1; 
switch (personType) 
{ 
    case 1: 
    { 
    /// 
    break; 
    } 
    case 2: 
    { 
    /// 
    break; 
    } 
    case 3: 
    { 
     /// 
     break; 
    } 
    ... 
} 
0

L'ambito non è affatto strano. L'ambito di una variabile locale è dal punto in cui è definito fino alla fine del blocco in cui è definito. Pertanto, le varie variabili emp appartengono ciascuna alla fine del blocco che inizia con { dopo l'istruzione switch e finisce nel corrispondente }. Non c'è niente di speciale nelle etichette case; non cambiano l'ambito delle variabili.

Problemi correlati