Что вы видите, это разница между использованием 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);
}
+1 Интересный вопрос! –