** MODIFICA: Ci sono diverse opzioni che potrebbero funzionare. Si prega di votare/commentare in base alle proprie opinioni in merito.Metodo di rifasamento con più punti di ritorno
sto lavorando sulla pulizia e l'aggiunta di funzionalità per il metodo aC# con la seguente struttura di base:
public void processStuff()
{
Status returnStatus = Status.Success;
try
{
bool step1succeeded = performStep1();
if (!step1succeeded)
return Status.Error;
bool step2suceeded = performStep2();
if (!step2suceeded)
return Status.Warning;
//.. More steps, some of which could change returnStatus..//
bool step3succeeded = performStep3();
if (!step3succeeded)
return Status.Error;
}
catch (Exception ex)
{
log(ex);
returnStatus = Status.Error;
}
finally
{
//some necessary cleanup
}
return returnStatus;
}
Ci sono molti passi, e nella maggior parte dei casi passo x devono avere successo, al fine di procedere al passaggio x + 1. Ora, ho bisogno di aggiungere alcune funzionalità che verranno sempre eseguite alla fine del metodo, ma che dipende dal valore restituito. Sto cercando dei consigli su come rifarlo in modo pulito per ottenere l'effetto desiderato. La scelta più ovvia sarebbe quella di mettere la funzionalità che dipende dal valore restituito nel codice chiamante, ma non sono in grado di modificare i chiamanti.
Una possibilità:
public void processStuff()
{
Status returnStatus = Status.Success;
try
{
bool step1succeeded = performStep1();
if (!step1succeeded)
{
returnStatus = Status.Error;
throw new Exception("Error");
}
bool step2succeeded = performStep2();
if (!step2succeeded)
{
returnStatus = Status.Warning;
throw new Exception("Warning");
}
//.. the rest of the steps ..//
}
catch (Exception ex)
{
log(ex);
}
finally
{
//some necessary cleanup
}
FinalProcessing(returnStatus);
return returnStatus;
}
Questo sembra un po 'brutto per me. Invece, potrei buttare direttamente dai metodi performStepX(). Tuttavia, questo lascia il problema di impostare la variabile returnStatus in modo appropriato nel blocco catch di processStuff(). Come avrai notato, il valore restituito in caso di fallimento di una fase di elaborazione dipende da quale fase è fallita.
public void processStuff()
{
Status returnStatus = Status.Success;
try
{
bool step1succeeded = performStep1(); //throws on failure
bool step2succeeded = performStep2(); //throws on failure
//.. the rest of the steps ..//
}
catch (Exception ex)
{
log(ex);
returnStatus = Status.Error; //This is wrong if step 2 fails!
}
finally
{
//some necessary cleanup
}
FinalProcessing(returnStatus);
return returnStatus;
}
Apprezzerei qualsiasi suggerimento che potreste avere.
Sono decisamente d'accordo con la prima metà della risposta. Ci sono alcune buone risposte qui che migliorerebbero la leggibilità senza violare quel principio. – jheddings
Così com'è, non si comporta come richiesto. Ho bisogno di fare qualcosa alla fine del metodo che dipende dal valore di ritorno. E, come ho detto, non posso cambiare il codice chiamante. – Odrade
Mi dispiace @Odrade Ho dimenticato che era necessario modificare la funzionalità. Vedi se la mia risposta aggiornata ti aiuta. –