2011-06-20 10 views
9

Estaba tratando de usar Enumerable.SequenceEqual(x,y) como esperaba que funcione según el método Object.Equals(x,y), que devuelve falso si x o y es nulo, y verdadero si ambos son nulos (para casos nulos).¿Por qué Enumerable.SequenceEqual arroja una excepción si algún parámetro es nulo?

Sin embargo, Enumerable.SequenceEqual(x,y) arroja una excepción si algún parámetro es una referencia nula y no devolverá verdadero si recibe dos valores nulos.

En mi código compruebo la igualdad de cobro con bastante frecuencia, así que creé un método que imita el comportamiento Object.Equals para secuencias, pero me pregunto cuál es la lógica detrás de dicho comportamiento predeterminado, ¿existe quizás un método existente sin excepciones en nulos?

+1

Bueno, el hecho de que el primer parámetro sea 'null' arroja una excepción, tiene sentido, ya que es un método de extensión. Normalmente se invoca como 'x.SequenceEqual (y)' y así imita 'x.Equals (y)', que también arrojaría si 'x' donde' null'. –

Respuesta

4

Bueno, el MSDN documentation establece explícitamente que arroja un ArgumentNullException en caso de que cualquiera de las secuencias pasadas sea nula. Supongo que es para mantener la coherencia con el "comportamiento estándar" donde un objeto arroja un NullReferenceException cuando intenta desreferenciarlo. Considere esto:

List<int> foo = null; 
foo.SequenceEqual(new List<int>()); 

esto estaría bien como SequenceEqual es un método de extensión y por lo tanto puede manejar un objeto nulo, sino que también sería confuso. Cada método de extensión provisto por Linq sigue este comportamiento hasta donde yo sé. Además, no es necesario que maneje casos nulos especiales para cada método de extensión (sería necesario ponerse de acuerdo sobre el comportamiento razonable y agregar lógica adicional y mantenerla y probarla). Decir que es ilegal lo hace más robusto (contra errores lógicos) y coherente desde una perspectiva marco. Utilizo mucho Linq y nunca me encontré con ese problema, solo me aseguro de que todas mis secuencias no sean nulas. Reduce mucho el desorden de código (elimina muchas comprobaciones nulas del código).

2

El punto en el que se comprueba la igualdad de secuencia no es cuando se lanza esa excepción. Se está lanzando antes como un validador de argumentos. Considere el método:

public static bool SequenceEquals<T>(this IEnumerable<T> source, IEnumerable<T> target) 
{ 
    // Stuff 
} 

Nos explícitamente que comprobar que source y target no son nulos, ya que si alguno de ellos es, entonces no puede cheque por la igualdad secuencia. Este es un estado impracticable, y el resultado de SequenceEquals debe estar regido por el contenido de los enumerables, no por el estado de los enumerables. Si incluyera el último, al devolver false, ¿cómo sabría la persona que llama si está fallando realmente porque las secuencias no son iguales, o si uno o ambos de los enumerables son null?

Si no inicia una ArgumentNullException aquí, el CLR habría arrojado una NullReferenceException cuando intentas acceder a una de las null enumerables. Simplemente decir Object reference not set to an instance of an object es mucho menos útil que The argument <something> cannot be null.

Recuerde, el tipo de excepción arrojada es típicamente uno de los indicadores más útiles acerca de por qué se produjo una excepción.

Cuestiones relacionadas