2010-04-22 5 views
9

J'ai une requête d'insertion qui retourne un int. Basé sur ce int, je souhaiterais peut-être lancer une exception. Est-ce approprié de faire dans une déclaration de commutateur? Normalement, j'ajoute des instructions break aux commutateurs, mais elles ne seront pas touchées. Est-ce un mauvais design? S'il vous plaît partager des opinions/suggestions avec moi.Can/Faut-il lancer des exceptions dans une instruction C# switch?

Merci, ~ ck à San Diego

+2

Il semblerait que vous essayiez de mapper des codes retour à des exceptions. Votre intention est claire, donc je dirais que cette solution est bonne. –

Répondre

3

Je ne suis pas d'accord avec vos conventions de nommage des variables;), mais je ne vois pas pourquoi ce que vous avez fait serait inapproprié. Cela semble être une manière assez élégante de traduire une erreur d'un média à un autre.

Je suppose que votre "requête d'insertion" est une forme de proc stocké.

+0

Oui, monsieur, vous avez raison. Merci. – Hcabnettek

0

Je pense que c'est OK. Il semble que vous mappez un code de retour à une exception, en utilisant une instruction switch. Tant qu'il n'y a pas trop de cas, ce n'est pas un problème.

1

Si possible, il serait probablement mieux si vous jetiez où le résultat a échoué est réglé, sinon vous finissez d'avoir à faire les deux résultats de vérification et lancer. Mais pourrait ne pas être possible bien sûr.

Aussi, je ferais vos chaînes d'erreur en ressources ou des constantes avec des espaces réservés afin que vous ne devez pas changer plusieurs endroits si vous voulez modifier le libellé.

4

Pas de problème ... pourquoi ce serait un mauvais design?

Alternativement, puisque le type d'exception est le même dans tous les case s, vous pouvez construire une table de recherche pour les messages d'erreur. Cela vous éviterait une duplication de code. Par exemple:

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)); 
} 

Dans les messages eux-mêmes, vous pouvez sélectionner le paramètre approprié avec {0}, {1}, etc.

0

Il n'y a rien de mal à l'approche que vous prenez. Les instructions switch sont beaucoup plus faciles à lire que les instructions if/then (et potentiellement plus rapides). L'autre chose que vous pourriez faire est de charger les exceptions possibles dans un

Dictionary<Result_Type, Exception> 

et de tirer l'exception à partir de là. Si vous avez beaucoup d'instructions switch, cela rendra le code plus compact (et vous pourrez les ajouter et les supprimer à l'exécution si nécessaire).

+0

Un dictionnaire pourrait être bon, mais il devrait être un 'Dictionary ' ou quelque chose comme 'Dictionary ', ou 'Dictionary ', avec une définition appropriée classe d'exception-factory (et interface, le cas échéant) définie quelque part. Lancer un objet Exception existant détruira au minimum la trace de la pile. Si deux threads rencontrent simultanément le même type d'exception, le partage d'un objet d'exception entre eux peut entraîner le gestionnaire d'un thread à voir la trace de pile de l'autre thread. – supercat

+0

Oui, pas le meilleur exemple d'utilisation d'un dictionnaire pour ça. Si quelque chose vous devez probablement stocker le type d'exception, et non l'exception réelle elle-même. – kemiller2002

+0

Malheureusement, stocker le type d'exception n'est pas utile pour beaucoup, car à moins d'utiliser Reflection (une préposition quelque peu douteuse dans le contexte d'une exception), il n'y a pas moyen de générer une exception de type exception. ce type. – supercat

12

Pourquoi pas?

De Le langage de programmation C#, troisième éd. par Anders Hejlsberg et al page 362:

La liste d'instructions d'une section de commutation se termine généralement dans un break, goto case ou déclaration goto default, mais toute construction qui rend le point final de la liste des états injoignable est autorisée . [...] De même, une instruction throw ou return transfère toujours le contrôle ailleurs et n'atteint jamais son point de fin.Ainsi, l'exemple suivant est valide:

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

Je ne vois pas de problème avec l'aide d'un interrupteur dans votre cas.

La plus grande considération devrait être de savoir si les exceptions elles-mêmes sont appropriées. En règle générale, les exceptions ne doivent être utilisées que lorsqu'une situation se situe en dehors des limites du comportement attendu. Les exceptions ne doivent pas être utilisées comme logique de flux de programme. Dans votre cas, vous êtes probablement autorisé à les utiliser en fonction du code que je vois.

0

Peut-être que je vous demande de différer toutes les réponses ici ..

au lieu d'avoir à changer dans le code, je préférerais passer le result à la classe ClientException & laissez-le décider quelle chaîne il doit montrer ont alors plutôt un interrupteur laid dans tous les sens pour créer divers messages

Mon code ressemblerait à ceci:

throw new ClientException(result, cTbx.Text); 

donc, même si vous pouvez jeter des erreurs dans switch...case, vous pouvez l'éviter tout est à ma portée

+1

À quel point le constructeur ClientException aurait la même logique de commutateur, mais il devrait avoir des ruptures. – Yishai

+0

ou un if ... else :) – Sunny

+0

Je downvote parce que cette "solution" ne fait que déplacer le problème. Cela ne fait aucune différence réelle. –

Questions connexes