2009-04-25 9 views
6

Digamos que tengo un método de extensiónC#: La mejor práctica para la validación de "este" argumento a los métodos de extensión

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

Para validar el argumento e, debo:

A) si (e == null) throw new NullReferenceException()
B) si (e == null) throw new ArgumentNullException ("e")
C) No comprobar el correo

¿Cuál es el consenso?

Mi primer pensamiento es siempre validar los argumentos, por lo que lanzo una ArgumentNullException. Por otra parte, dado que TakeRandom() se convierte en un método de e, tal vez debería ser una NullReferenceException. Pero si se trata de una NullReferenceException, si trato de usar un miembro de e dentro de TakeRandom(), se lanzará NullReferenceException de todos modos.

Tal vez debería aprovechar el Reflector y averiguar qué hace el framework.

+0

Hoy tuve exactamente esta pregunta en mi cabeza. Tengo que amar StackOverflow.com - Tiene todas las respuestas (y preguntas, a veces varias veces). :) – orj

Respuesta

9

Debería lanzar una ArgumentNullException. Está intentando hacer una validación de argumentos y, por lo tanto, debe arrojar una excepción ajustada a la validación de argumentos. NullReferenceException no es una excepción de validación de argumentos. Es un error de tiempo de ejecución.

No olvide que los métodos de extensión son solo métodos estáticos debajo del capó y se pueden llamar como tales. Aunque en apariencia puede parecer razonable arrojar una NullReferenceException en un método de extensión, no tiene sentido hacerlo para un método estático. No es posible determinar la convención de llamadas en el método y, por lo tanto, ArgumentException es la mejor opción.

Además, nunca deberías lanzar explícitamente una NullReferenceException. Esto solo debe ser lanzado por el CLR. Existen diferencias sutiles que ocurren al lanzar explícitamente excepciones que normalmente solo lanzan los CLR.

Esto también está cerca de una víctima de la siguiente

4

Para coherencia con los operadores Enumerable LINQ, arroje una ArgumentNullException (no una NullReferenceException).

Haría la validación en el método TakeRandom porque la traza de la pila dejará en claro que es TakeRandom que objeta que se le dé un argumento nulo.

1

Tal vez estoy loco, pero ya que es un argumento, me lanzo una ArgumentNullException:/

general Sin embargo, la regla general es arrojar Excepciones derivadas de System.ApplicationException cuando sea posible. NullReferenceException es algo que lanzaría framework/CLR. existen

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

dos categorías de excepciones en la excepción clase base:

la lengua común clases de excepción de tiempo de ejecución predefinidos derivados de SystemException.Las clases de excepción de aplicación definidas por el usuario derivaron de ApplicationException.

+0

"lanzar Excepciones que deriven de System.ApplicationException cuando sea posible" - ese fue el consejo original de Microsoft para .NET 1.0, pero ahora ha cambiado y ApplicationException está en desuso. Google por las razones – Joe

+0

@Joe por favor, elabore. En el caso extremadamente raro que crearía mis propias excepciones ... ¿Por qué no heredaría ApplicationException? Gracias –

+0

@Deviant: no tengo el artículo a mano, pero creo que esto se discute en las Pautas de diseño del marco. El pensamiento original detrás de ApplicationException era que tendría bloques "catch (ApplicationException ex)" y haría algo diferente en una excepción de aplicación frente a una excepción del sistema. Resultó que no era útil y requeriría que el código de la Aplicación cubra todas las excepciones del Sistema en una excepción de Aplicación. Las Pautas de diseño del marco también tienen buenas reglas para cuándo crear sus propias excepciones y cuándo detectar excepciones. –

Cuestiones relacionadas