有人可以解释这里发生了什么吗?如何这两个这些都是真的吗?
[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'?或者单身不等于17?
答案 0 :(得分:6)
可空类型的.Sum()
方法忽略所有null
值:
MSDN: Enumerable.Sum Method (IEnumerable<Nullable<Int32>>)
<强>说明强>
结果不包含null值。
如果您通过+
向null
添加任何号码,则结果为null
。
正如Andrew Hare所说,向null
添加一个数字是没有意义的:null
不是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);
}