2015-11-04 15 views
7

Ho il seguente codice che tenta di catturare un riferimento null. Quindi genera un'eccezione con un motivo più chiaro per l'errore specificato nella proprietà del messaggio.IndexNotFoundException versus NullReferenceException

Che tipo di eccezione deve inviare? Un IndexOutOfRangeException?

var existing = this.GetByItemId(entity.ItemId); // int or long 
if (existing == null) 
{ 
    throw new IndexOutOfRangeException("The specified item does not exist."); 
} 

var price = existing.Price; 

o uno NullReferenceException?

var existing = this.GetByItemId(entity.ItemId); 
if (existing == null) 
{ 
    throw new NullReferenceException("The specified item does not exist."); 
} 

var price = existing.Price; 

oppure, dovremmo lasciare che l'eccezione faccia il suo corso?

var existing = this.GetByItemId(entity.ItemId); 
var price = existing.Price; // NullReferenceException coming your way 

Il motivo si tende a non farlo ultima opzione, è che il NullReferenceException default è luce dettaglio ed appena afferma

riferimento non impostato a un'istanza di un oggetto.

Quale, a dire il vero, potrebbe benissimo essere il messaggio di errore più inutile in C#.

+2

Dal tuo codice, 'IndexOutOfRangeException' non sembra adattarsi: mi aspetto un'eccezione di questo tipo quando accedo a una struttura indicizzabile (array, elenco) con indice intero e l'indice utilizzato non è compreso nell'intervallo. il tuo 'GetItemById (int itemID)' sembra utilizzare un id di qualcosa per una ricerca, non un numero intero come indice –

+0

è il 'esistente' null o è il valore'existing.Price' null, cose abbastanza diverse che sarebbero. I tuoi esempi indicano comunque entrambi i modi. –

+0

Se mancano dettagli nell'eccezione di riferimento null, forse si vorrà ereditarlo e creare la propria eccezione con le proprietà necessarie? O qualsiasi altra vecchia eccezione personalizzata con qualche descrizione informativa, è probabilmente quello che farei ... – Culme

risposta

9

userei un'eccezione personalizzato per questo (qualche cosa come ItemNotFoundException).

A NullReferenceException o IndexOutOfRangeException potrebbero essere lanciati da qualcos'altro all'interno di this.GetByItemId() o nel Framework da qualche parte.

Il chiamante potrebbe voler eseguire un'azione di follow-up se l'elemento non compare nella raccolta (ad esempio aggiungendolo). L'utilizzo della propria eccezione consente al chiamante di chiamare l'catch in modo specifico e reagire di conseguenza.

+0

Ho seguito il tuo consiglio. Ora abbiamo una ItemNotFoundException. – Junto

5

Un'eccezione personalizzata con la descrizione della vostra scelta dovrebbe farlo:

if (existing == null) 
    { 
     throw new EntityMissingException("'existing' does not exist (ironic, isn't it?)."); 
    } 
+2

Non gettare mai la classe base di tutte le eccezioni. Ciò rende impossibile scrivere blocchi di cattura focalizzati. –

+1

Sono sinceramente interessato al motivo per cui questo è downvoted =) L'OP sostiene che la NullReferenceException è "light on detail". L'uso di un testo di errore personalizzato può fornire molti dettagli, se necessario. D'accordo, ha degli svantaggi quando si tratta di gestire ecc., Ma è davvero così male? Io tendo a farlo molto, quindi apprezzerò davvero i suggerimenti sul perché sia ​​cattivo, non sto solo sbraitando perché sono stato svalutato! =) – Culme

+0

Grazie a @Daniel. Avrei dovuto passare con l'errore personalizzato non proprio così veloce e sporco, probabilmente hai ragione. – Culme

1

Il NullReferenceException indica che si desidera accedere a un membro di riferimento null. Normalmente non si dovrebbe mai lanciarlo (a meno che non si implementi un interprete o qualcosa di simile).

Se il entity è un parametro, quindi direi che questo è un ArgumentException. Se dici che questo non dovrebbe mai accadere in circostanze normali, allora questo è piuttosto un InvalidOperationException.