en python, il existe ce code de manipulation d'exception utile:
if (!IsReadOnly) { T newobj; try { newobj = DataPortal.Update<T>(this); List<string> keys = new List<string>(BasicProperties.Keys); foreach (string key in keys) { BasicProperties[key] = newobj.BasicProperties[key]; } } catch (DataPortalException) { // TODO: Implement DataPortal.Update<T>() recovery mechanism } }
10 Réponses :
Vous pouvez faire quelque chose comme ceci:
if (!IsReadOnly) { T newobj = null; try { newobj = DataPortal.Update<T>(this); } catch (DataPortalException) { // TODO: Implement DataPortal.Update<T>() recovery mechanism } if (newobj != null) { List<string> keys = new List<string>(BasicProperties.Keys); foreach (string key in keys) { BasicProperties[key] = newobj.BasicProperties[key]; } } }
Ce serait la déclaration vide comme Hits
Je préférerais voir le reste du code en dehors de l'essai / attraper, il est donc clair que l'exception que vous essayez d'attraper vient de venir de et que vous ne attrapez pas accidentellement une exception que vous n'essayez pas de Catch.
Je pense que l'équivalent le plus proche de la Python Essayez / Catch est d'utiliser une variable booléenne locale à mémoriser si une exception a été lancée ou non. P>
bool success; try { foo(); success = true; } catch (MyException) { recover(); success = false; } if (success) { bar(); }
+1 pour la partie "Poignée de l'exception correctement". Si vous ne pouvez pas récupérer à partir de l'exception, vous devriez probablement arrêter de faire ce que vous faites immédiatement. Si vous ne pouvez pas vous empêcher d'arrêter gracieusement, refacteur pour que vous puissiez.
+1, mais je dois demander: comment va-t-il mieux que de mettre l'appel au bar () juste avant la prise?
@David: avec le code que j'ai donné, si la fonction code> code> jette une myException, il ne sera pas attrapé mais avec votre suggestion, elle sera prise. La méthode que j'ai montrée plus proche du Essayez: Catch: Sinon: Code> Construire dans ces exceptions soulevées dans le
sinon code> ne sont pas capturés.
J'utilise ce modèle assez souvent et j'initialise généralement succès code> à
false code> - enregistre moi une ligne de code dans le bloc code>.
Parfois, il est approprié de pré_do; essayez {do} attraper (erreur) {récupérer} else {do_more}; post_do; code>. Cela ne signifie pas que l'erreur n'a pas été récupérée ou que le code n'a pas complètement abandonné ce qu'il avait besoin.
c # n'a pas un tel concept, vous êtes donc simplement laissé avec trois options, p>
Il suffit de mettre votre bloc "autre" avant em> la prise. Ensuite, il n'exécutera que si l'exécution de code n'atteint que le point: try
{
fee();
fi();
foe();
fum();
/// put your "else" stuff here.
/// It will only be executed if fee-fi-foe-fum did not fail.
}
catch(Exception e)
{
// handle exception
}
La différence est qu'il y a 1 ligne qui devrait lancer une exception et que vous vous attendez à ce que cela puisse arriver et l'attraper. Si une ligne différente a jeté l'exception qui pourrait être quelque chose que vous ne voulez pas attraper, car cela peut indiquer un bogue réel.
@ Davy8 Dans ce cas, vous devez soit être a) Attraper uniquement le type d'exception spécifique que vous attendez, ou b) placez le code que vous ne vous attendez pas à générer une exception à l'extérieur b> de cet essai. .catch Block. Dans tous les cas, vous devriez toujours attraper des exceptions qui se produisent afin que vous puissiez échouer gracieusement.
Il est proche, mais ce n'est pas assez équivalent. Si c'est juste à l'extérieur de l'essai / attrape, il s'exécutera, que la première section a jeté une exception, mais elle ne devrait exécuter que lorsque la première partie n'a pas lancé. Il est possible que le même type d'exception puisse être jeté, de sorte que la capture d'une exception spécifique est une amélioration, mais n'est pas exactement la même chose.
@DavidLively: Vous ne devez pas échouer gracieusement d'un bug qui ne devrait pas exister. Si une sorte de cohérence doit être maintenue, le code d'appel devrait s'assurer que et signaler l'erreur.
@Noctiskkytower par opposition aux bugs que devrait-il exister i>? Je conviens que l'utilisation d'exceptions pour le contrôle de flux est mauvaise. Si, par exemple, vous expédiez une bibliothèque qui doit masquer l'exception réelle, laissant la journalisation jusqu'à l'appelant peut être inacceptable. Il y a des circonstances - parler à un périphérique externe. Par exemple, où ce type de problème ne peut pas être résolu par la conception.
Si vous aimez demander le pardon plutôt que l'autorisation, une exception ne signifie pas nécessairement un bug. Je m'excuse pour mon libellé. Certaines échecs ou exceptions peuvent être corrects tandis que d'autres sont clairement une erreur ou un bogue dans le programme. La réponse de Daniel Newby peut ne pas être préférée, mais j'ai aimé la façon dont elle est traduite de Python à C #.
Permettez-moi de répéter une idée d'un Question similaire Stackoverflow . Vous ne pouvez pas faire cela directement, mais vous pouvez écrire une méthode qui encapsule le comportement dont vous avez besoin. Regardez la question initiale pour voir comment implémenter la méthode (si vous n'êtes pas familier avec Lambda Expressions et Func Code> Délégués). L'utilisation pourrait ressembler à ceci:
Solution barbare: Créez une classe d'autre dérivée de l'exception, lancez une instance de celui-ci à la fin du bloc d'essai et utilisez Je me sens si sale. P> attraper (autre) {...} code> pour gérer les autres trucs . P>
Je ne sais pas quoi faire ici - cela demande i> A -1 vote, mais je suis assez amusé pour hésiter à le faire.
Sinon à Python n'atteignent pas toutes les autres exceptions. Sinon, est seulement couru quand aucune exception n'est présente.
Ceci pourrait être évité pour être évité mais ne peut pas goto (notez que je n'ai presque aucune connaissance de C #, donc je n'ai aucune idée si cela fonctionne).
Qu'en est-il de quelque chose comme P>
try { ... } catch(Exception ex) { ... goto Jump_past_tryelse } ...//Code to execute if the try block DID NOT fail Jump_past_tryelse: ...
Je vous ai presque donné un +1 simplement pour offrir tout le pub avec votre «goto»!
"Offrir tout le pub" ==?
@ Romana.Taycher 8 ans plus tard, googling "offrant tout le pub" code> rendement exactement 1 résultat de recherche: cette page. Je suppose que nous ne saurons jamais ...
if (!IsReadOnly) { T newobj; bool Done; try { newobj = DataPortal.Update<T>(this); List<string> keys = new List<string>(BasicProperties.Keys); foreach (string key in keys) { BasicProperties[key] = newobj.BasicProperties[key]; } Done = true; } catch (DataPortalException) { // TODO: Implement DataPortal.Update<T>() recovery mechanism Done = false; } finally { if (newobj != null && Done == false) { List<string> keys = new List<string>(BasicProperties.Keys); foreach (string key in keys) { BasicProperties[key] = newobj.BasicProperties[key]; } } } }
avec Exemple 1: strong> (puisque c # version 7 ) p> Si vous préférez qui doit seulement être là une fois dans votre code, puis utilisez le modèle pour les méthodes anonymes comme suit P> où vous devez entendre un code dans un contexte sûr. P> Essayez-le dans Notes: strong> p>
retour; code> pour quitter l'erreur. Li>
exécuter code> est utilisée. LI>
exécuter code> ne doit pas nécessairement être une fonction locale, Exemple 2 Strong> fonctionne avec des versions C # plus anciennes, ainsi que li>
ul> p>
J'ai toujours détesté à l'aide d'essayer des blocs de capture à cause de cela. Il n'y a aucun moyen de séparer le code de rupture et n'a pas cassé le code.
Vote à proximité comme duplicata exact: Stackoverflow.com/questions/1177438/c-try-catch-else a>
Cela pourrait être une duplication, mais cette question n'a jamais été suffisamment répondue. Après avoir lu sur les réponses, j'aime le concept de Daniel Newby le meilleur.