2010-09-09 17 views
8

¿Puede alguien explicar lo que está sucediendo aquí? Howcome ambos estas cosas son verdad?LINQ Comportamiento agregado de tipos que aceptan nulos.

[TestMethod] 
public void WhatIsGoingOnHere() 
{ 
    List<int?> list = new List<int?> { 1, 2, 3, null, 5, 6 }; 
    Assert.AreEqual(17, list.Sum()); 

    int? singleSum = 1 + 2 + 3 + null + 5 + 6; 

    Assert.IsNull(singleSum); 
} 

Específicamente, ¿por qué el método Sum() no devuelve 'nulo'? O el singleSum no es igual a 17?

+0

+1 pregunta interesante! –

Respuesta

4

Lo que está viendo es la diferencia entre usar Enumerable.Sum y realmente agregar los valores usted mismo.

Lo importante aquí es que el null no es cero. A primera vista, podría pensar que singleSumdebería ser igual a 17, pero eso significaría que tendríamos que asignar semántica diferente a null según el tipo de datos de la referencia. El hecho de que este sea un int? no hace diferencia - null es null y nunca debe ser semánticamente igual con la constante numérica 0.

La implementación de Enumerable.Sum está diseñada para omitir cualquier valor que sea null en la secuencia, por lo que está viendo el comportamiento diferente entre las dos pruebas. Sin embargo, la segunda prueba devuelve correctamente null ya que el compilador es lo suficientemente inteligente como para saber que si agrega algo a null obtendrá null.

Aquí está la implementación de Enumerable.Sum que acepta un parámetro de int?:

public static int? Sum(this IEnumerable<int?> source) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull("source"); 
    } 
    int num = 0; 
    foreach (int? nullable in source) 
    { 
     // As you can see here it is explicitly designed to 
     // skip over any null values 
     if (nullable.HasValue) 
     { 
      num += nullable.GetValueOrDefault(); 
     } 
    } 
    return new int?(num); 
} 
+0

Entiendo totalmente por qué singelSum es nulo, no 17 - porque null es simplemente nulo ... totalmente contigo :) Supongo que mi pregunta era más, ¿cómo es que Sum() no volvió nula, también ... – kiwipom

6

El método de tipos anulables .Sum() ignora todos null valores:

MSDN:Enumerable.Sum Method (IEnumerable<Nullable<Int32>>)

Observaciones

El resultado no incluye valores que son nulos.

Mientras que si se agrega a través de cualquier número + a null el resultado es null.

Como señaló Andrew Hare, no tiene sentido agregar un número a null: null no es 0; simplemente no es un número.

+0

gracias por el enlace ... parece que funciona así. Lo entiendo ahora - aplausos :) – kiwipom

+0

realmente lo siento, no pude marcar ambas respuestas como correctas ... +1 de mí, de todos modos! gracias – kiwipom

Cuestiones relacionadas