我正在创建一些通过API返回表单的对象,这些对象是从数据库值派生的,包括数据库中可能为null的值,但在我的API上下文中不能为null(我正在获取来自多个表的数据,所以我知道如果一个表中的字段为空,我可以从另一个表中获取合法的值):
List<ResultsByLineShiftSlot> returnResults = new List<ResultsByLineShiftSlot>();
foreach (LineShiftSlot ls in db.LineShiftSlots.OrderBy(ls => ls.ScheduledDateAndTime).Where(ls => ls.ProductionDate == slotDate &&
ls.ShiftId == shiftId &&
ls.LineId == lineId &&
ls.Quantity > 0 &&
ls.BlendId != null))
{
var recordedResult = db.LineShiftSlotResults.FirstOrDefault(r => r.LineShiftSlotId == ls.Id);
if (recordedResult != null)
{
ResultsByLineShiftSlot returnResult = new ResultsByLineShiftSlot
{
BlendId = recordedResult.BlendId
};
}
else
{
ResultsByLineShiftSlot returnResult = new ResultsByLineShiftSlot
{
BlendId = ls.BlendId ?? 0
};
}
}
return returnResults;
在上面的示例中,BlendId在LineShiftSlots中可以为null,但在LineShiftSlotResults中不能为空。
在这个可知可空变量包含非空值的上下文中,哪个更好?
我应该使用空合并运算符:
BlendId = ls.BlendId ?? 0
或者我应该使用.Value():
BlendId = ls.BlendId.value()
两者都编译,似乎工作。
在这种情况下,它们在功能上是否相同?使用一个比另一个更好的做法?我知道.value()可能会返回异常,而null合并运算符则不能,但在这种情况下.value永远不能为null。
答案 0 :(得分:1)
在一般情况下,它们在语义上不相同。
labelId = recordValue.labelId.Value;
这意味着我知道价值不能是null
。如果我的假设错了,就扔掉。
另一方面,
labelId = recordValue.labelId ?? 0;
labelId = recordValue.labelId.GetValueOrDefault();
这两个意味着值可能为空,如果发生这种情况,请忽略它,考虑它是正常的,并用默认值替换它。
在这种情况下,我会使用GetValueOrDefault()
,这会让它更明显(JIT将内联此方法)。
但是,您的代码等同于这个更简单的替代方法:
labelId = recordValue.labelId ?? otherValue;
答案 1 :(得分:0)
在这种情况下,代码将是相同的,但是您考虑了以下
labelId = recordValue.labelId ?? otherValue
基本上是以下
if(recordValue.labelId != null){
labelId = recordValue.labelId.Value;
}
else
{
labelId = otherValue;
}