Linq Sum(a+b) 不同于 Sum(a) + Sum(b)
Linq Sum(a+b) different than Sum(a) + Sum(b)
当我们使用 nullable 类型时,如 int?
或 decimal?
,Sum(a+b)
有时不同于 Sum(a)+Sum(b)
工作示例:
class SomeClass
{
public int? One { get; set; }
public int? Two { get; set; }
}
static void Main(string[] args)
{
var list = new List<SomeClass>()
{
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { Two = 2 }
};
Console.WriteLine(list.Sum(_ => _.One + _.Two)); // 12 // wrong
Console.WriteLine(list.Sum(_ => _.One) + list.Sum(_ => _.Two)); // 14
Console.ReadLine();
}
人们会期望两个总和(打印在 Console
上)写出 14
。但是第一个似乎忽略了一些元素。
那是因为最后一个元素:
new SomeClass { Two = 2 }
没有 One
,在那种情况下 One
是 null
并且 null+a
和 a
一个非 null
整数是 null
.
现在,按照 Linq.Sum
中的规定,总和会忽略 null
个值。因此最后一项不算。
第二个版本没有遇到这个问题,因为One
s的求和会求和除最后一项之外的所有项,而Two
s的求和会求和所有项。
正如@Chris 所说,您确实可以使用 Null coalescing operator One ?? 0
。这个运算符 returns 0
如果 One
是 null
,在那种情况下,即使其中一个参数是 null
,它也会总结为零因此 return 一个数字。
当我们使用 nullable 类型时,如 int?
或 decimal?
,Sum(a+b)
有时不同于 Sum(a)+Sum(b)
工作示例:
class SomeClass
{
public int? One { get; set; }
public int? Two { get; set; }
}
static void Main(string[] args)
{
var list = new List<SomeClass>()
{
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { One = 1, Two = 2 },
new SomeClass { Two = 2 }
};
Console.WriteLine(list.Sum(_ => _.One + _.Two)); // 12 // wrong
Console.WriteLine(list.Sum(_ => _.One) + list.Sum(_ => _.Two)); // 14
Console.ReadLine();
}
人们会期望两个总和(打印在 Console
上)写出 14
。但是第一个似乎忽略了一些元素。
那是因为最后一个元素:
new SomeClass { Two = 2 }
没有 One
,在那种情况下 One
是 null
并且 null+a
和 a
一个非 null
整数是 null
.
现在,按照 Linq.Sum
中的规定,总和会忽略 null
个值。因此最后一项不算。
第二个版本没有遇到这个问题,因为One
s的求和会求和除最后一项之外的所有项,而Two
s的求和会求和所有项。
正如@Chris 所说,您确实可以使用 Null coalescing operator One ?? 0
。这个运算符 returns 0
如果 One
是 null
,在那种情况下,即使其中一个参数是 null
,它也会总结为零因此 return 一个数字。