Perché utilizzare mai l'eccezione throw (in C #) tranne per lo sviluppo della libreria di classi? [duplicare]

-3

Perché dovrei mai generare eccezioni nel codice? (eccetto per uno scenario specifico in cui sto sviluppando una libreria di classi che i consumatori di esso, non vorranno / saranno in grado di cambiare).

Per essere più specifici, c'è qualche ragione per farlo:

class EmailSender
{
   public void SendEmail(string recipient, string subject, string content)
   {
       if (string.IsNullOrEmpty(recipient))
       {
           throw new ArgumentNullException("exception text...");
       }

       // Send the email
   }

}

Al posto di questo:

class EmailSender
{
   public bool SendEmail(string recipient, string subject, string content)
   {
       bool result = false;

       try
       {
           if (string.IsNullOrEmpty(recipient))
           {
              logger.Error("Error text...");
           }
           else
           {
              // Send the email
              result = true;
           }
       }
       catch (Exception ex)
       {
           logger.Error(ex);
       }

       return result;
   }
}

Considera che questa classe è un codice interno e non qualcosa che spedirò come una DLL o un progetto open source.

    
posta Uri Abramson 01.12.2015 - 18:25
fonte

2 risposte

6

Stai chiedendo perché non sempre gestisci l'errore all'interno dello stesso metodo in cui viene rilevato l'errore?

È raro che tu possa gestire un errore allo stesso livello di dove viene rilevato il problema, è possibile solo perché l'esempio è forzato. Ad esempio, cosa succede se la logica "invia la posta" contiene più chiamate al metodo:

VerifyAdresses(recipient);
ConnectToSmtpServer();
PostMessage();

Che cosa succede se viene rilevato un errore in VerifyAdresses o ConnectToSmtpServer ? Se il metodo registra l'errore e continua felicemente (come nel tuo esempio), il PostMessage verrà eseguito in ogni caso, probabilmente con un errore molto più grave come risultato.

Devi gestire gli errori al livello in cui è possibile ripristinare con garbo. Ad esempio è possibile gestire l'errore nella logica di mailing non inviando la posta. Ma non puoi gestire con garbo un errore localmente in VerifyAdresses() se quell'errore impedisce l'intera operazione di invio di una mail. Devi essere in grado di eseguire il backup dello stack di chiamate (eventualmente di più passaggi) al livello in cui l'errore può essere gestito in modo ragionevole.

Modifica: OK, ti stai davvero chiedendo perché non utilizzare i codici di esito positivo / errore in stile C anziché le eccezioni. Questa discussione è stata battuta a morte, ma è sufficiente dire che il quadro ha fatto la scelta per voi. I codici risultato utilizzati coerentemente possono in teoria essere buoni come eccezioni (se molto più noiosi e soggetti a errori), ma poiché il framework utilizza già eccezioni, sarebbe incredibilmente confuso e uno spreco di risorse usare entrambi eccezioni e codici risultato nella stessa base di codice.

    
risposta data 01.12.2015 - 19:22
fonte
0

Il software generalmente comprende livelli di funzionalità. (vale a dire il livello dell'applicazione, il livello di persistenza, il livello di rete, il livello del database, ecc.)

Una "libreria" è un livello di funzionalità che è stato distanziato dal tuo codice essendo stato spostato in un file binario separato, ma questo è solo un tecnicismo, il punto è che si tratta solo di un altro livello di funzionalità.

Un livello di funzionalità generalmente comunica errori al livello precedente generando eccezioni.

Quindi, se tutto il software che stai scrivendo vive in un singolo strato sottile come una pasta per pizza croccante, allora sì, suppongo che non ci sia alcun bisogno per te di gettare un'eccezione.

Ma se mai farai qualcosa di non banale nella tua carriera, allora lavorerai ovviamente contemporaneamente a diversi livelli, e quindi avrai la necessità di lanciare un'eccezione in un livello, per essere catturati (o meno) da uno strato sopra.

    
risposta data 01.12.2015 - 19:56
fonte