2012-12-20 11 views
6

Quello che ho è semplice switchproblema inizializzazione delle variabili in un'istruzione switch

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

In questa situazione compilatore mi dice che

locale myControl variabile non potrebbe essere inizializzato prima di accedere

Quindi, qual è il modo migliore per evitare questa situazione?

Un'opzione è di inizializzare myControl prima dell'istruzione switch. Ma in questo caso faccio un'altra initalizzazione inutile.

CASO 1:

Control myControl = null; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

opzione successiva è quella di cambiare secondo caso con default. Dopo che il compilatore avrà "capito" che myControl sarà comunque inizializzato e non genererà eccezioni.

CASO 2:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    default: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

Ma questo caso non sembra così buono, perché dopo l'aggiunta di alcune nuove proprietà al mio enum che farà di default per tutti gli altri tipi (sviluppatore può facilmente dimenticare di cambiare codice qui o non può essere necessario inizializzare myControl per altri tipi di enumerazione).

Qual è l'approccio migliore in tali situazioni?

+0

Il compilatore ti dà la risposta .. basta impostare su null local il tuo errore "variabile myControl potrebbe non essere inizializzato prima di accedere a" – MethodMan

risposta

5

L'esempio di codice indica che verrà sempre utilizzata la variabile myControl dopo il blocco di interruttori. In questo caso, è necessario inizializzare la variabile o aggiungere una clausola default (come indicato).

Se si è preoccupati che possa essere introdotto un nuovo valore enumerato, è possibile generare un'eccezione significativa nella clausola default. Ciò ti proteggerà dall'ottenere un più ambiguo NullReferenceException quando tenti di dereferenziare la variabile in un secondo momento.

+2

+1 per lanciare un'eccezione quando il caso 'default' è colpire. Anche una buona alternativa. –

+1

Grazie a tutti :) La clausola predefinita con eccezione significativa di lancio è un buon approccio. –

+0

Chuck Norris può deferenza in modo sicuro un riferimento Null senza ottenere una NullReferenceException – user93353

3

Terza opzione: validare un esempio è stato creato prima di procedere (invece di fare affidamento su di esso viene assegnato):

Control mycontrol = null; 
switch (x){ 
    // ... 
} 
if (myControl != null){ 
    // add to controls list, manipulate, etc. 
} 

Si potrebbe anche aggiungere default: caso di caduta-through per il valore default(TabType):

switch (x){ 
    case TabType.Two: 
    // ... 
    case TabType.Three: 
    // ... 
    case TabType.One: 
    default: 
    // .. 
} 
+1

Il tuo secondo caso era il suo secondo caso. – Servy

+1

@ServyL sì, ma ho reso una dichiarazione esplicita invece di esentare il valore 'predefinito (Tabtype)' e solo usando 'default:'. –

+0

@DJKRAZE Errore di battitura, risolto. – Servy

2

Penso che lo standard default esista specificamente per queste situazioni.

l'aggiunta di alcune nuove proprietà al mio enum che farà di default per tutti gli altri tipi

Essa permetterà il vostro codice di lavorare su premessa di default (un'eccezione o impostato su un valore ben noto) e quindi la vostra il codice funziona anche per situazioni non pianificate in precedenza.

Ovviamente, quando si implementano nuove proprietà e si prevede un comportamento diverso del codice, omettere di aggiornare questa opzione sarà un bug facile da individuare.

0

Devi fare una delle due opzioni; specificare il valore iniziale prima del switch o aggiungere un caso default in modo che il compilatore sappia che lo switch inizializzerà la variabile.

Suggerirei che se lo switch non inizializza la variabile è possibile che tu voglia solo lanciare un'eccezione. In tal caso, basta aggiungere quel codice al caso default.In questo modo è chiaro nei test quando uno sviluppatore si dimentica di aggiungere case per un nuovo valore enum, invece di lavorare silenziosamente.

1

faccio un altro inizializzazione del inutili

Anche io non piace.

Come molti hanno già detto, aggiungi una sezione aggiuntiva default: all'istruzione switch. Come questo:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    myControl= ...; 
    break; 

    case TabType.View: 
    myControl= ...; 
    break; 

    default: 
    throw new Exception("Unexpected value of x: " + x);   
} 

myPageView.Controls.Add(myControl); 

Questo perché dalla tua domanda si capisce che si sapere che x avrà sempre uno di questi due valori. Il compilatore non lo sa. Il codice sopra lo dirà così.

Problemi correlati