Question

Voici une question pour exposer mon manque d'expérience: j'ai une méthode DoSomething () <)> qui lève une exception si elle ne parvient pas à le faire proprement. Si cela échoue, j’essaie plusieurs fois la méthode moins précise Faire quelque chose d’environ () , dans l’espoir qu’elle trouve une solution suffisamment bonne; Si cela échoue également, j'appelle enfin DoSomethingInaccurateButGuaranteedToWork () . Toutes les trois sont des méthodes appartenant à cet objet.

Deux questions: d’abord, est-ce que cette tendance (certes moche) est acceptable ou existe-t-il un moyen plus élégant?

Deuxièmement, quel est le meilleur moyen de savoir combien de fois j'ai appelé Faire quelque chose d'approximativement () , étant donné qu'il est susceptible de générer une exception? Je garde actuellement une variable iNoOfAttempts dans l'objet, et imbrique des blocs d'essai ... c'est horrible et j'ai honte.

Était-ce utile?

La solution

Vous ne devez jamais utiliser d'exceptions pour contrôler le flux de votre application.

Dans votre cas, je regrouperais les trois méthodes en une seule méthode et lui indiquerais quelle approche avait réussi, peut-être avec une énumération ou quelque chose du genre.

Autres conseils

Renvoyez un code d'erreur au lieu de lancer une exception.

Si les méthodes utilisées par ces méthodes échouent en générant des exceptions, saisissez-les toutes dans la même méthode et prenez les mesures appropriées, comme augmenter un compteur et renvoyer un code d'erreur.

   bool result = DoSomething();
   while (!result && tries < MAX_TRIES) {
       result = DoSomethingApproximately(); //This will increment tries
       if (tries > THRESHOLD) {
           result = DoSomethingThatAlwaysWorks();
       }
   }

Déplacez les pointeurs de fonction dans un itinéraire de structure. Juste pour pimenter, je vais utiliser une file d’attente et un peu de LINQ.

Queue<Action> actions = new Queue<Action>(new Action[] {
   obj.DoSomething,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingGuaranteed
});

actions.First(a => {
   try {
      a();
      return true;
   } catch (Exception) {
      return false;
   }
});

Que diriez-vous de (pseudocode):

try{ return doSomething(); }
catch(ExpectedException) { ...not much here probably...}

for(i = 0 to RETRIES){
try{ return doSomethingApproximately; }
catch(ExpectedException) { ...not much here probably...}
}

doSomethingGuaranteed();

Addendum:

Je vous recommande vivement de ne pas utiliser de valeurs de retour spéciales, car cela signifie que chaque utilisateur de la fonction doit savoir que certaines des valeurs de retour sont spéciales. En fonction de la plage de la fonction, il peut être judicieux de renvoyer une partie ordinaire de la plage qui peut être traitée normalement, par ex. une collection vide. Bien entendu, cela peut rendre impossible la distinction entre l’échec et le "droit" answer étant la collection vide (dans cet exemple).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top