2010-04-22 6 views
9

Ho una query inserto che restituisce un int. Basandomi su questo, potrei voler fare un'eccezione. È appropriato farlo all'interno di un'istruzione switch?È possibile/È possibile generare eccezioni in una istruzione switch C#?

switch (result) 
     { 

      case D_USER_NOT_FOUND: 
       throw new ClientException(string.Format("D User Name: {0} , was not found.", dTbx.Text)); 
      case C_USER_NOT_FOUND: 
       throw new ClientException(string.Format("C User Name: {0} , was not found.", cTbx.Text)); 
      case D_USER_ALREADY_MAPPED: 
       throw new ClientException(string.Format("D User Name: {0} , is already mapped.", dTbx.Text)); 
      case C_USER_ALREADY_MAPPED: 
       throw new ClientException(string.Format("C User Name: {0} , is already mapped.", cTbx.Text)); 
      default: 

       break; 
     } 

Normalmente aggiungo istruzioni di interruzione agli interruttori ma non verranno colpiti. È un cattivo design? Si prega di condividere eventuali opinioni/suggerimenti con me.

Grazie, ~ ck a San Diego

+2

Sembra che tu stia cercando di associare i codici di ritorno alle eccezioni. La tua intenzione è chiara, quindi direi che questa soluzione va bene. –

risposta

3

io in realtà non sono d'accordo con le convenzioni di denominazione delle variabili;), ma non vedo il motivo per cui quello che hai fatto sarebbe inappropriato. Sembra un modo abbastanza elegante di tradurre un errore da un mezzo a un altro.

Suppongo che la "query di inserimento" sia una forma di stored proc.

+0

Sì signore, lei ha ragione. Grazie. – Hcabnettek

0

Penso che sia OK. Sembra che tu stia mappando un codice di ritorno a un'eccezione, usando un'istruzione switch. Finché non ci sono troppi casi, questo non è un problema.

1

Se possibile, probabilmente sarebbe meglio se si butta ovunque sia impostato il risultato fallito, altrimenti si finisce con il dover eseguire sia il controllo dei risultati che il lancio. Ma potrebbe non essere possibile, naturalmente.

Inoltre, vorrei convertire le stringhe di errore in risorse o costanti con i segnaposto in modo da non dover modificare più posizioni se si desidera modificare il testo.

4

Nessun problema ... perché questo sarebbe un cattivo design?

In alternativa, poiché il tipo di eccezione è uguale in tutti i case s, è possibile creare una tabella di ricerca per i messaggi di errore. Ciò ti farebbe risparmiare una duplicazione del codice. Per esempio:

static private Dictionary<int, string> errorMessages; 
static 
{ 
    // create and fill the Dictionary 
} 

// meanwhile, elsewhere in the code... 
if (result is not ok) { 
    throw new ClientException(string.Format(errorMessages[result], cTbx.Text, dTbx.Text)); 
} 

Nei messaggi stessi, è possibile selezionare il parametro desiderato con {0}, {1}, ecc

0

Non c'è niente di sbagliato con l'approccio che sta assumendo. Le istruzioni switch sono molto più facili da leggere rispetto alle dichiarazioni if ​​/ then (e potenzialmente anche più veloci). L'altra cosa che potreste fare è caricare le possibili eccezioni in un

Dictionary<Result_Type, Exception> 

e tirare l'eccezione da lì. Se disponi di molte istruzioni switch, questo renderebbe il codice più compatto (e potrai aggiungerli e rimuoverli in fase di esecuzione se necessario).

+0

Un dizionario potrebbe essere buono, ma dovrebbe essere un 'dizionario ' o qualcosa di simile a 'Dizionario ', o 'Dizionario ', con una definizione appropriata classe di fabbrica di eccezione (e interfaccia, se applicabile) definita da qualche parte. Lanciare un oggetto Exception esistente distruggerà almeno la traccia dello stack. Se due thread incontrano simultaneamente lo stesso tipo di eccezione, la condivisione di un oggetto eccezione tra di loro potrebbe far sì che il gestore di un thread veda l'altra traccia dello stack del thread. – supercat

+0

Sì, non è il miglior esempio di usare un dizionario per questo. Se è necessario archiviare probabilmente il tipo di eccezione, e non l'eccezione vera e propria. – kemiller2002

+0

Sfortunatamente, la memorizzazione del tipo di eccezione non è utile per molto, poiché a meno che non si utilizzi Reflection (una preposizione un po 'rischiosa nel contesto di un'eccezione) non esiste un modo generale per, dato un tipo di eccezione, generare un'eccezione di quel tipo – supercat

12

Perché no?

Da Il linguaggio di programmazione C#, terzo ed. da Anders Hejlsberg et al, pagina 362:

La lista istruzioni di una sezione di commutazione in genere termina in una, goto case o goto default dichiarazione break, ma è consentito alcun costrutto che riproduce il punto di fine della lista istruzioni irraggiungibile . [...] Allo stesso modo, una dichiarazione throw o return trasferisce sempre il controllo altrove e non raggiunge mai il punto finale.Così il seguente esempio è valido:

switch(i) { 
case 0: 
    while(true) F(); 
case 1: 
    throw new ArgumentException(); 
case 2: 
    return; 
} 
0

non vedo alcun problema con l'utilizzo di un interruttore nel tuo caso.

La considerazione più forte dovrebbe andare a stabilire se le eccezioni sono appropriate. In generale, le eccezioni dovrebbero essere utilizzate solo quando si verifica una situazione che è al di fuori dei limiti del comportamento previsto. Le eccezioni non dovrebbero essere utilizzate come logica di flusso del programma. Nel tuo caso probabilmente stai bene usarli in base al codice che vedo.

0

Forse mi permetto di dissentire da tutte le risposte qui ..

Invece di dover passare nel codice, avrei preferito passare il result alla classe ClientException & lasciarlo decidere che cosa stringa di cui ha bisogno per mostrare piuttosto che avere un interruttore brutto tutto il luogo per creare vari messaggi

il mio codice sarebbe simile:

throw new ClientException(result, cTbx.Text); 

quindi, anche se si può buttare errori in switch...case, puoi evitarlo tutto è come fare il mio

+1

A quel punto il costruttore ClientException avrebbe la stessa logica di commutazione, ma avrebbe dovuto avere interruzioni. – Yishai

+0

o un if ... else :) – Sunny

+0

Ho downvoted perché questa "soluzione" sposta semplicemente il problema. Questo non fa alcuna differenza reale. –