Il servizio dovrebbe generare un'eccezione o tornare quando nessun elemento specificato per la cancellazione

12

Ho un pezzo di codice che può essere rappresentato come:

public class ItemService {

    public void DeleteItems(IEnumerable<Item> items)
    {
        // Save us from possible NullReferenceException below.
        if(items == null)
            return;

        foreach(var item in items)
        {
            // For the purpose of this example, lets say I have to iterate over them.
            // Go to database and delete them.
        }
    }
}

Ora mi chiedo se questo è l'approccio giusto o dovrei lanciare un'eccezione. Posso evitare l'eccezione, perché il ritorno sarebbe lo stesso di iterare su una raccolta vuota, il che significa che non viene comunque eseguito alcun codice importante, ma d'altra parte probabilmente sto nascondendo dei problemi da qualche parte nel codice, perché qualcuno dovrebbe voler chiamare DeleteItems con null parametro? Questo potrebbe indicare che c'è un problema da qualche altra parte nel codice.

Questo è un problema che di solito ho con i metodi nei servizi, perché la maggior parte di essi fa qualcosa e non restituisce un risultato, quindi se qualcuno trasmette informazioni non valide non c'è nulla da fare per il servizio, quindi restituisce.

    
posta FCin 24.05.2018 - 09:12
fonte

5 risposte

58

Queste sono due domande diverse.

Dovresti accettare null ? Dipende dalla tua politica generale su null nel codice base. A mio parere, vietare null ovunque tranne dove è documentato in modo esplicito è una buona pratica, ma è ancora meglio fare pratica attenersi alla convenzione che il tuo codice base ha già.

Dovresti accettare la collezione vuota? A mio parere: SÌ, assolutamente. È molto più difficile limitare tutti i chiamanti a raccolte non vuote che fare la cosa matematicamente giusta, anche se sorprende alcuni sviluppatori che sono incerti con il concetto di zero.

    
risposta data 24.05.2018 - 10:06
fonte
9

Valore nullo

Come già detto @ KilianFoth, attenetevi alla vostra politica generale. Se questo è per trattare null come "abbreviazione" per una lista vuota, fallo in questo modo.

Se non hai una norma coerente sui valori di null , ti consigliamo la seguente:

null dovrebbe essere riservato per rappresentare situazioni che non possono essere espresse dal tipo "normale", ad es. usando null per rappresentare "Non so". E questa è una buona scelta, poiché tutti coloro che cercano di usare questo valore con noncuranza otterranno un'eccezione, che è la cosa giusta.

Usare null come una scorciatoia per una lista vuota non si qualifica in questo modo, poiché esiste già una rappresentazione perfetta, essendo una lista con elementi zero. Ed è una scelta tecnicamente sbagliata, poiché costringe ogni parte del tuo codice a gestire gli elenchi per verificare la stenografia valida null .

Lista vuota

Per un metodo DeleteItems() , passare una lista vuota significa in effetti non fare nulla. Lo permetterei come argomento, non facendo un'eccezione, ma tornando rapidamente.

Ovviamente, il chiamante potrebbe verificare prima gli elementi zero e saltare la chiamata DeleteItems() in quel caso. Se stiamo parlando di un'API web, per ragioni di efficienza il chiamante dovrebbe farlo effettivamente per evitare il traffico inutile e le latenze di andata e ritorno. Ma non credo che la tua API dovrebbe imporlo.

    
risposta data 24.05.2018 - 12:13
fonte
1

Genera un'eccezione e gestisci i null nel codice chiamante.

Come regola di progettazione cerca di evitare null come valori di parametro. Ridurrà NullPointerExceptions in generale, poiché i nulli saranno davvero un'eccezione.

Oltre a ciò, guarda il resto del tuo codice. Se questo è uno schema comune nel tuo progetto, rimani coerente.

    
risposta data 24.05.2018 - 09:32
fonte
0

In generale, le eccezioni di lancio dovrebbero essere riservate a situazioni eccezionali, ad esempio se il codice non ha una linea di condotta ragionevole da adottare nel contesto corrente.

Puoi applicare quel processo di pensiero a questa situazione. Dato che si tratta di una classe pubblica con un metodo pubblico, hai un'API pubblica e in teoria nessun controllo su ciò che viene passato ad esso.

Il tuo codice non ha alcun contesto su come lo chiama (come non dovrebbe), e non c'è nulla che tu possa ragionevolmente fare con un valore nullo. Questo sarebbe certamente un candidato per un ArgumentNullException .

    
risposta data 24.05.2018 - 10:24
fonte
0

Questa domanda sembra non riguardare le eccezioni, ma circa null è un argomento valido.

Quindi, prima di tutto devi decidere se null è un valore consentito per il tuo argomento di quel metodo. Se lo è, allora non hai bisogno di un'eccezione. Se non lo è, allora hai bisogno di un'eccezione.

Se si desidera consentire a null , o meno, è discutibile, come dimostrato da molti e molti successi su Google. Il che significa che non otterrai una risposta chiara, ed è un po 'di opinione e tradizione nel posto in cui lavori.

Un'altra area di contesa è se una funzione di libreria dovrebbe essere veramente rigida su tali cose, o il più indulgente possibile, a patto che non stia cercando di "aggiustare" parametri errati. Confronta questo con il mondo dei protocolli di rete, del trasferimento della posta ecc. (Che sono contratti di interfaccia, proprio come i metodi di programmazione). Lì, di solito, la politica è che il mittente dovrebbe conformarsi il più strettamente possibile al protocollo, mentre il ricevitore dovrebbe fare di tutto per essere in grado di lavorare con qualsiasi cosa stia arrivando.

Quindi devi decidere: è davvero il lavoro di un metodo di libreria applicare criteri piuttosto grandi come null di gestione? Soprattutto se la tua libreria è utilizzata anche da altre persone (chi potrebbe avere politiche diverse).

Probabilmente sbaglierei sul lato di permettere valori di null , definire e documentare la loro semantica (cioè null = empty array in questo caso), e non lanciare un'eccezione, a meno che 99% di il tuo altro codice simile (codice di stile "libreria") esegue l'altro modo "round.

    
risposta data 24.05.2018 - 13:28
fonte

Leggi altre domande sui tag