我对下一种情况下的编译器效率感到好奇:
double total = list.Sum(x => x.Value) ?? 0;
问:编译器会生成一次或两次执行Sum函数的代码吗?
它可以产生类似的东西:
double total = list.Sum(x => x.Value) == null ? 0 : (double)list.Sum(x => x.Value);
或
double temp = list.Sum(x => x.Value);
total = temp == null ? 0 : (double)temp;
答案 0 :(得分:8)
您的代码毫无意义,因为即使对所有空值求和也会导致0。
var d = new int?[]{null,null};
d.Sum().Dump(); //0
...所以Enumerable.Sum()
永远不会产生你想要防范的null
值。
答案 1 :(得分:4)
代码将执行Sum
一次。这就是将新操作符引入语言的重点。您可以通过引入具有副作用的条件并验证副作用仅应用一次来验证这一点:
int? x = 5;
int y = x++ ?? 100;
执行此代码后,x
为6
,而不是7
。
答案 2 :(得分:0)
??
运算符仅适用于可空类型,double
不是可空类型,因此此代码不会编译。
同样,.Sum()
扩展方法永远不会在此列表中返回null
,它将始终返回0
。