Domanda

Ecco una domanda per esporre la mia mancanza di esperienza: ho un metodo DoSomething () che genera un'eccezione se non riesce a farlo in modo pulito. Se fallisce, provo più volte il metodo meno accurato DoSomethingApproximately () nella speranza che possa trovare una soluzione sufficientemente buona; se anche questo fallisce, finalmente chiamo DoSomethingInaccurateButGuaranteedToWork () . Tutti e tre sono metodi appartenenti a questo oggetto.

Due domande: in primo luogo, questo schema (per definizione brutto) è accettabile o esiste un modo più elegante?

In secondo luogo, qual è il modo migliore per tenere traccia di quante volte ho chiamato DoSomethingApproximately () , dato che è probabile che generi un'eccezione? Attualmente sto mantenendo una variabile iNoOfAttempts nell'oggetto e annidando i blocchi di prova ... questo è orribile e mi vergogno.

È stato utile?

Soluzione

Non dovresti mai usare eccezioni per il flusso di controllo della tua applicazione.

Nel tuo caso raggrupperei i tre metodi in un unico metodo e gli farei restituire quale particolare approccio ha avuto successo, forse con un enum o qualcosa del genere.

Altri suggerimenti

Restituisce un codice di errore invece di generare un'eccezione.

Se i modi in cui questi metodi falliscono generano eccezioni, prendili tutti nello stesso metodo e prendi le misure appropriate, come aumentare un contatore e restituire un codice di errore.

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

Vai a tutti i puntatori a funzioni in un percorso di struttura. Solo per rendere più piccante, userò una coda e alcuni 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;
   }
});

Che ne dici di (pseudocodice):

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:

Consiglio vivamente di non utilizzare valori di restituzione speciali, perché ciò significa che ogni singolo utente della funzione deve sapere che alcuni dei valori di restituzione sono speciali. A seconda della gamma della funzione, può essere sensato restituire una parte ordinaria della gamma che può essere gestita normalmente, ad es. una collezione vuota. Naturalmente, ciò potrebbe rendere impossibile distinguere tra fallimento e "diritto". risposta essendo la raccolta vuota (in questo esempio).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top