2010-09-09 2 views
8

Может кто-нибудь объяснить, что здесь происходит? Howcome как эти вещи верны?LINQ Совокупное поведение типов с нулевым значением

[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); 
} 

В частности, почему метод Sum() не возвращает 'null'? Или singleSum не равен 17?

+0

+1 Интересный вопрос! –

ответ

4

Что вы видите, это разница между использованием Enumerable.Sum и фактическим добавлением значений самостоятельно.

Важная вещь здесь null не равна нулю. На первый взгляд вы думаете, что singleSumдолжен равен 17, но это означало бы, что нам нужно было бы присвоить другую семантику null на основе типа данных ссылки. Тот факт, что это int?, не имеет значения - null - null и никогда не должен быть семантически равным с числовой константой 0.

Реализация Enumerable.Sum предназначена для пропускания любого значения, которое является null в последовательности, поэтому вы видите различное поведение между двумя тестами. Однако второй тест справедливо возвращает null, поскольку компилятор достаточно умен, чтобы знать, что добавление чего-либо к null дает null.

Вот реализация Enumerable.Sum, которая принимает параметр 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

Я полностью понимаю, почему singelSum имеет значение null, а не 17 - потому что null - это просто null ... полностью с вами там :) Я думаю, мой вопрос был больше, howcome Sum() тоже не возвращал значение null ... – kiwipom

6

Метод обнуляемых типов .Sum() игнорирует все null значения:

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

Замечания

Результат не содержит значения, которые являются нуль.

Принимая во внимание, если добавить любое число к null через + результат null.

Как отметил Андрей Харе, нет смысла добавлять число до null: null не 0; это просто не число.

+0

спасибо за ссылку ... похоже, что это как раз то, как она работает. Я получаю это сейчас - приветствия :) – kiwipom

+0

искренне жаль, что я не мог отметить оба этих ответа как правильно ... +1 от меня, во всяком случае! спасибо – kiwipom

Смежные вопросы