2009-04-25 7 views
6

Diciamo che ho un metodo di estensioneC#: Le migliori pratiche per la convalida di "questo" argomento in metodi di estensione

public static T TakeRandom<T>(this IEnumerable<T> e) 
{ 
    ... 

Per convalidare l'argomento e, devo:

A) se (e == null) throw new NullReferenceException()
B) se (e == null) throw new ArgumentNullException ("e")
C) Non controllare la posta

Qual è il consenso?

Il mio primo pensiero è quello di convalidare sempre gli argomenti, quindi lanciare un'eccezione ArgumentNullException. Poi di nuovo, dato che TakeRandom() diventa un metodo di e, forse dovrebbe essere una NullReferenceException. Ma se si tratta di una NullReferenceException, se provo a utilizzare un membro di e all'interno di TakeRandom(), verrà comunque generata NullReferenceException.

Forse dovrei fare un picco usando Reflector e scoprire cosa fa il framework.

+0

Ho avuto esattamente questa domanda mi in testa oggi. Devi amare StackOverflow.com - Ha tutte le risposte (e le domande, a volte più volte). :) – orj

risposta

9

Si dovrebbe generare una ArgumentNullException. Stai tentando di eseguire la convalida degli argomenti e quindi dovresti generare un'eccezione sintonizzata sulla convalida degli argomenti. NullReferenceException non è un'eccezione di convalida argomento. È un errore di runtime.

Non dimenticare, i metodi di estensione sono solo metodi statici sotto il cofano e possono essere chiamati come tali. Mentre può sembrare in superficie avere un senso per lanciare una NullReferenceException su un metodo di estensione, non ha senso farlo per un metodo statico. Non è possibile determinare la convenzione di chiamata nel metodo e quindi ArgumentException è la scelta migliore.

Inoltre, non si dovrebbe mai lanciare esplicitamente una NullReferenceException. Questo dovrebbe essere lanciato solo dal CLR. Ci sono sottili differenze che si verificano quando si lanciano esplicitamente eccezioni che vengono normalmente lanciate solo dal CLR.

Questo è anche vicino a una vittima dei seguenti

4

Per coerenza con gli operatori LINQ enumerabili, generare un'eccezione ArgumentNullException (non una NullReferenceException).

Effettuerò la convalida nel metodo TakeRandom perché la traccia dello stack renderà quindi chiaro che è TakeRandom a cui viene assegnato un argomento nullo.

1

Forse sono pazzo, ma dal momento che è un argomento, vorrei gettare un ArgumentNullException:/

generale la regola generale è di lanciare eccezioni che derivano da System.ApplicationException quando possibile. NullReferenceException è qualcosa che il framework/CLR genererebbe.

http://msdn.microsoft.com/en-us/library/system.exception(VS.71).aspx

due categorie di eccezioni esistono sotto l'eccezione classe base:

il linguaggio comune runtime classi di eccezioni predefinite derivati ​​da SystemException.Le classi di eccezione dell'applicazione definite dall'utente derivano da ApplicationException.

+0

"genera eccezioni che derivano da System.ApplicationException quando possibile" - questo era il consiglio originale di Microsoft per .NET 1.0, ma ora è stato modificato e ApplicationException è deprecato. Google per le ragioni. – Joe

+0

@Joe, per favore, elabora. Nel caso estremamente raro che creerei le mie eccezioni ... Perché non ereditare da ApplicationException? Grazie –

+0

@Deviant: non ho l'articolo a portata di mano, ma credo che questo sia discusso nelle Linee guida di progettazione di Framework. Il pensiero originale dietro ApplicationException era che avresti blocchi "catch (ApplicationException ex)" e avresti fatto qualcosa di diverso su un'eccezione dell'applicazione contro un'eccezione di sistema. Ciò si è rivelato non utile e richiedeva che il codice dell'applicazione includesse tutte le eccezioni di sistema in un'eccezione dell'applicazione. Le Linee guida per la progettazione di framework hanno anche buone regole per quando creare le proprie eccezioni e quando rilevare le eccezioni. –

Problemi correlati