Devo gettare eccezioni di protezione che saranno comunque lanciate dai metodi interni? [duplicare]

3

Ho un codice abbastanza semplice (C #):

    /// <summary>
    /// Truncates a string to a maximum length. 
    /// </summary>
    /// <param name="value">     The string to truncate. </param>
    /// <param name="maxLength"> The maximum length of the string. </param>
    /// <returns>
    /// The original string if its length is less than or equal to max length, else a truncated
    /// string of length maxLength.
    /// </returns>
    public static string Truncate(string value, int maxLength)
    {
        if(maxLength <= 0) throw new ArgumentOutOfRangeException("maxLength");

        if (string.IsNullOrEmpty(value)) return value;

        return value.Length <= maxLength ? value : value.Substring(0, maxLength);
    }

È chiaro che se maxLength è minore di 0, non posso usarlo come una lunghezza di stringa, quindi attualmente sto usando un'istruzione guardia per evitare valori maxLength non validi.

La mia domanda è: è buona o cattiva pratica usare questa istruzione di guardia, quando value.Substring genererà comunque la stessa eccezione? È solo un codice sprecato?

    
posta Nick Udell 02.09.2014 - 14:40
fonte

2 risposte

0

In generale, lo scopo del lancio dell'eccezione è di fornire la tua eccezione personale. Ad esempio, se Truncate fosse un metodo disponibile per l'uso in una libreria, chiamiamolo ABC, potrebbe essere utile avere tutte le eccezioni riconducibili a un'eccezione di base chiamata ABCException che proviene anche dalla libreria. In altre parole, per qualsiasi problema causato dalla libreria ABC, è possibile selezionarlo utilizzando l'eccezione di base ABCException . Questo è estremamente utile per identificare i problemi provenienti da una libreria specifica.

Un altro motivo per eseguire il tuo controllo è per un "controllo di integrità". In altre parole, sì, forse Substring lancia questa eccezione, ma se dovessi decidere domani che qualcosa dovrebbe essere fatto precedente per eseguire la chiamata Substring effettiva, il tuo codice potrebbe generare un'eccezione diversa e non rilevata anziché. Questo potrebbe rendere il debugging del problema molto più difficile poiché potresti scartare la possibilità che il problema si trovi in Truncate perché del fatto che Truncate è supposto da lanciare un'altra eccezione in tali circostanze. Chiamalo come vuoi, ma mi piace chiamarlo programmazione difensiva. È probabile? No, ma se ti costeranno solo 10 secondi per aggiungere, direi di andare avanti e aggiungerlo.

Si noti che non aggiungerei verifiche come queste a meno che non fossero metodi pubblici e quindi disponibili per essere chiamati da chiunque. Inoltre, nelle circostanze in cui il metodo è specificamente documentato come tale, non eseguirò nemmeno controlli. Se il chiamante non rispetta la documentazione di detto metodo, è responsabilità del chiamante, non del tuo.

Inoltre, se posso fare un'ottimizzazione minore, il contenuto dell'istruzione if dovrebbe essere lo scenario più probabile piuttosto che il meno probabile. Detto questo, lo riscriverei:

public static string Truncate(string value, int maxLength)
{
    if(maxLength > 0 && !string.IsNullOrEmpty(value)) 
        return value.Length <= maxLength ? value : value.Substring(0, maxLength);
    else
        throw new ArgumentOutOfRangeException("maxLength");
}

Spero che ti aiuti!

    
risposta data 02.09.2014 - 14:52
fonte
1

Si tratta dei contratti ai quali i tuoi metodi obbediscono.

Il tuo codice di esempio non mostra alcuna specifica di eccezione, quindi tecnicamente nessuno dovrebbe assumere nulla su ciò che accade per maxLength < 0 - non importa nemmeno se tu lanci un'eccezione affatto .

Se vuoi che quel comportamento faccia parte della tua semantica, dovrebbe essere documentato. Quindi decidere se lanciare o meno l'eccezione dipende da quale sia il contratto del metodo built-in. Se si è sicuri di lanciare questa eccezione, si può semplicemente fare affidamento su questo (anche se alcuni potrebbero sostenere che il lancio dell'eccezione in modo esplicito è ancora migliore a causa di problemi di leggibilità e di errori iniziali). Se non lo è, devi lanciare l'eccezione tu stesso.

    
risposta data 02.09.2014 - 14:47
fonte

Leggi altre domande sui tag