Pour un exemple typique if...else
de gestion des exceptions avec encapsulation, l'exemple suivant est-il une pratique recommandée pour éviter la duplication de code?
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
throw new Exception();
}
catch(Exception ex)
{
return null;
}
au lieu de...
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
return null;
}
}
catch(Exception ex)
{
return null;
}
Je sais qu'il y a une légère baisse de performances, mais je me demande si cela est considéré comme une pratique acceptable. Je fais actuellement la deuxième méthode - en particulier dans les cas où j'ai besoin de gérer des exceptions spécifiques différemment - mais je me demandais si la première méthode est appropriée pour les cas simples.
c#
exception-handling
grovesNL
la source
la source
Réponses:
L'utilisation de la gestion des exceptions pour le contrôle de flux est déconseillée par Microsoft.
Et une table ronde sur le sujet est disponible.
Cela étant dit, C # prend en charge cela, et je suppose que cela dépend de la condition rencontrée si une exception est la réponse la plus appropriée.
la source
Le hit de performance est très probablement négligeable, comme expliqué dans cette réponse .
Partons donc avec l'idée que la performance n'est pas un problème. Vous lancez
System.Exception
, juste pour déplacer l'exécution dans lacatch
clause . Jeter unBadControlFlowThatShouldBeRewrittenException
serait probablement exagéré.Décomposons cela. On a:
GetDataFromServer
(les noms de méthode doivent être PascalCase en C #), qui peut éventuellement lever une exception ou renvoyer unbool
.true
, exécutezProcessData
.null
autrement.On dirait que la méthode où ce code est écrit, fait simplement trop de choses.
GetDataFromServer
renvoyer unbool
ressemble à un défaut de conception, je m'attendrais à ce que cette méthode retourne les données qu'elle obtient du serveur , certainesIEnumerable<SomeType>
qui contiendraient 0 ou plusieurs éléments - c'est-à-dire que le chemin heureux renvoie n éléments où n> 0 , pas si heureux path retourne 0 élément, et unhappy path explose avec une exception non gérée, quelle qu'elle soit.Cela change beaucoup l'apparence de la méthode - encore une fois, il est difficile de dire si cela a du sens, car la publication d'origine n'a qu'un seul point de sortie (et donc ne compilerait pas, car tous les chemins de code ne renvoient pas de valeur ), donc ce n'est qu'une supposition folle:
Ici, vous regarderiez
ProcessData
et verriez qu'il est en train d'itérer leresult
et retournenull
s'il n'y a pas d'article dans leIEnumerable
.Maintenant, pourquoi la méthode revient-elle
null
? Le serveur était en panne? Y a-t-il un bug dans la requête? La chaîne de connexion utilise des informations d'identification incorrectes? Chaque fois que vousGetDataFromServer
explosez avec une exception à laquelle vous ne vous attendez pas, vous l'avalez, la fourrez sous le tapis et retournez unenull
valeur. Je recommande d'attraper des exceptions spécifiques dans ce cas et de consigner tout le reste; le débogage sera beaucoup plus facile de cette façon.Avec une
catch
clause générale qui ne capture pas l'exception, il devient assez difficile de diagnostiquer quoi que ce soit. Je ferais le moins possible à la place:Maintenant, vous pouvez au moins casser et inspecter
e
si les choses tournent mal.TL; DR : Non, lever et intercepter des exceptions pour le contrôle de flux n'est pas une bonne idée.
la source
dans votre première réponse, il y a un impact sur les performances qui n'a pas besoin d'être là.
lorsque vous quittez l'instruction if pour entrer dans l'instruction Catch alors que vous n'avez pas à faire changer de direction, pour ainsi dire.
si vous voulez le
return null;
faire dans l'instruction else et non dans une capture qui est interceptée après avoir été levée à partir de l'instruction else.Ne s'applique probablement pas à votre code réel , mais pour le code générique que vous avez donné, il s'applique.
Les normes disent que vous ne devriez pas faire ça.
Les normes disent que vous devriez le faire comme ça, (encore une fois basé sur le code générique donné dans OP)
et puisque vous n'avez aucune exception spécifique que vous attrapez, vous ne devriez même pas avoir de prise d'essai ici.
vous souhaitez voir les exceptions lorsqu'elles se produisent afin de pouvoir résoudre le problème qui crée l'exception.
la source
Pourquoi pas beaucoup plus simple:
Si un gestionnaire d'exceptions doit exister, il doit être dans ProcessData ()
la source
ProcessData()
au niveau supérieur?ProcessData()
lève une exception maintenant, elle n'est pas gérée. Je le veuxreturn null
à ce niveau siProcessData()
jette une exception, sans se modifierProcessData()
.