如何让DefaultIfEmpty返回null而非默认值?
问题描述
我有一个包含4个可空double字段的类:
public class myClass { public double? i1; public double? i2; public double? i3; public double? i4; }
还有4个可能包含不同值或为空的列表,示例如下:
List<double> inputs1 = new List<double> { 1, 2, 3 }; List<double> inputs2 = new List<double> { 4, 5 }; List<double> inputs3 = new List<double> { }; List<double> inputs4 = new List<double> { 8, 9 };
我想创建一个myClass实例列表,包含这些值的所有可能组合。为了避免复杂的foreach循环(实际应用中有更多列表和类字段),我使用了以下LINQ表达式:
List<myClass> myObjects = ( from double? input1 in inputs1.DefaultIfEmpty() from double? input2 in inputs2.DefaultIfEmpty() from double? input3 in inputs3.DefaultIfEmpty() from double? input4 in inputs4.DefaultIfEmpty() select new myClass() { i1 = input1, i2 = input2, i3 = input3, i4 = input4 } ).ToList();
原本期望用DefaultIfEmpty()实现:如果任一列表为空(比如示例中的inputs3),仍能创建对象,且对应字段保持null。但实际DefaultIfEmpty()返回的是0,导致i3变成0而非null。尝试使用DefaultIfEmpty((double?)null)时,编译器不接受该语法,请问该如何解决?
解决方案
问题根源在于输入列表是List<double>类型,而非List<double?>,直接传递(double?)null给DefaultIfEmpty会因为类型不匹配报错。可以通过以下两种方式解决:
方法一:Cast转换+DefaultIfEmpty(null)
先将列表元素转换为可空double类型,再调用DefaultIfEmpty(null),此时参数类型与序列匹配,空列表会返回包含null的序列:
List<myClass> myObjects = ( from input1 in inputs1.Cast<double?>().DefaultIfEmpty(null) from input2 in inputs2.Cast<double?>().DefaultIfEmpty(null) from input3 in inputs3.Cast<double?>().DefaultIfEmpty(null) from input4 in inputs4.Cast<double?>().DefaultIfEmpty(null) select new myClass() { i1 = input1, i2 = input2, i3 = input3, i4 = input4 } ).ToList();
方法二:提前处理输入序列
先判断列表是否为空,为空则直接返回包含null的序列,否则转换为可空double序列:
// 预处理每个输入列表 var inputSeq1 = inputs1.Any() ? inputs1.Cast<double?>() : new[] { (double?)null }; var inputSeq2 = inputs2.Any() ? inputs2.Cast<double?>() : new[] { (double?)null }; var inputSeq3 = inputs3.Any() ? inputs3.Cast<double?>() : new[] { (double?)null }; var inputSeq4 = inputs4.Any() ? inputs4.Cast<double?>() : new[] { (double?)null }; // 生成组合实例 List<myClass> myObjects = ( from input1 in inputSeq1 from input2 in inputSeq2 from input3 in inputSeq3 from input4 in inputSeq4 select new myClass() { i1 = input1, i2 = input2, i3 = input3, i4 = input4 } ).ToList();
内容的提问来源于stack exchange,提问作者Justin8051
相关产品推荐
相关产品推荐

