ArgumentNullException o NullReferenceException del método de extensión?

¿Cuál sería el mejor tipo de excepción para lanzar cuando se invoca un método de extensión en una instancia nula (donde el método de extensión no lo permite)? Dado que los métodos de extensión no son más que métodos estáticos, podría argumentar que debería ser ArgumentNullException, pero por otro lado se usan como métodos de instancia, por lo que podría ser más natural usar la NullReferenceException. Tomemos el siguiente ejemplo:

public static string ToInvariantString(this IFormattable value, string format) { return value.ToString(format, CultureInfo.InvariantCulture); } 

De esta forma, se lanzará una NullReferenceException si el parámetro de valor es nulo.

El otro ejemplo sería:

 public static string ToInvariantString(this IFormattable value, string format) { if (value == null) throw new ArgumentNullException("value"); return value.ToString(format, CultureInfo.InvariantCulture); } 

EDITAR: en algunas de las respuestas ha señalado que los métodos de extensión se pueden llamar como un método estático y en esos casos una excepción de referencia nula sería incorrecta, que es un gran punto, y en realidad una de mis preocupaciones, no estoy seguro de por qué Olvidé mencionar eso en la pregunta en primer lugar.

Alguien también señaló que está mal lanzar una NullReferenceException, y sí, lo es. Es por eso que no lo tiro, simplemente dejo que suceda (deje que CLR lo lance) al no guardar el método.

Creo que estoy a favor de ArgumentNullException (eso es lo que he usado hasta ahora) pero sigo pensando que hay al menos espacio para argumentar en contra de la NullReferenceException, ya que parece más natural en la mayoría de los lugares donde se usará el método.

En general, con excepciones incluidas, debe tratar un método de extensión como si fuera un método estático normal. En este caso, debe lanzar una ArgumentNullException.

Lanzar una NullReferenceException aquí es una mala idea por algunas razones

  • Una referencia nula en realidad no ocurrió, por lo que ver uno es contrario a la intuición
  • Lanzar una NullReferenceException y hacer que ocurra una NullReferenceException produce excepciones discerniblemente diferentes (una forma de ver la diferencia es el código de error). Esto es cierto de muchas excepciones que arroja el CLR.

Ver cuándo puedes atrapar una StackOverflowException (una publicación que hice sobre este tema).

  • Es perfectamente legal llamar a un método de extensión como si fuera un método regular. En ese caso, ciertamente no exceptuaría una NullReferenceException, sino una ArgumentNullException.

Aparte de todas las otras respuestas (que son buenas), creo que vale la pena mirar lo que hace Microsoft en aras de la coherencia … y los métodos de extensión en Enumerable arrojan ArgumentNullException hasta donde puedo ver.

Como los métodos de extensión se pueden usar en C # 2.0, y se pueden llamar como métodos estáticos (NO TIENE que usarlos como métodos de extensión), debe usar ArgumentNullException.

El hecho de que parezcan métodos del tipo no significa que sean, o siempre se llamen como uno.

Desde el punto de vista del usuario, el método se ve y actúa como un método de instancia, por lo que si yo fuera ellos, esperaría ver una NullReferenceException.

Dicho esto, sugeriría arrojar uno u otro explícitamente en el código, en lugar de simplemente “pasar” para arrojar uno como en su primer ejemplo.

ArgumentNullException. No es necesario llamar a los métodos de extensión como si fueran métodos de instancia. Puede llamarlos como si fueran métodos normales. NullReferenceException sería completamente incorrecto en ese caso.