【发布时间】:2015-03-27 12:17:43
【问题描述】:
我正在创建一些对象以通过 API 返回到表单,这些对象是从数据库值派生的,包括在数据库中可能为空但在我的 API 上下文中不能为空的值(我正在获取数据来自多个表,所以我知道如果一个表中的字段为空,我可以从另一个表中获取合法值):
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 永远不能为空。
【问题讨论】:
-
为什么不只是
labelId = recordValue.labelId ?? otherValue?但是一般来说,如果您“知道”该值不是空值,则应该使用.Value,因为如果您的断言错误,则会引发异常,而空值合并运算符将隐藏该事实并默默地给您错误的值. -
如果您确定
FirstOrDefault将返回一个值,请使用First,否则您还应检查recordValue是否为null。 -
如果您要使用
Value,我建议您将其与HasValue配对,而不是null比较。 -
@crashmstr 记录集在我的实际代码中可能为空,也可能不为空(稍后我会添加一个更好的示例)。记录集是否为空决定了我将使用哪个源来填充返回对象。
-
@Lee 如果记录集为空,那么我从不同的数据源中提取。我添加了一个更完整的示例来说明。使用
.Value来引发错误的要点是我要问的要点,尽管在if (someValue != null) { nullableVariable = someValue.Value(); }的简化示例中显然永远不会触发该特定异常。
标签: c# null-coalescing-operator