我基本上是在尝试遍历大量数据,并将返回的数据查询转换为视图模型内更有限的对象。
而不是编写大量代码,我在列表上调用.ForEach(),然后将新条目添加到视图模型的列表中。
这很好用,但是有一个属性(地址)是可选的。
到达可选项目时,如果数据库中的项目没有条目,则会得到NullReferenceException
。
一个代码示例是:
var tmp = _context.Person.Include(x => x.Address).ToList();
tmp.ForEach(x => vm.List.Add(new IndexListItem()
{
Name = x.Name,
Address = x.Address.FirstLine + " " + x.Address.SecondLine,
ID = x.ID
}));
此后,我从该站点的另一个答案中发现,如果我更改地址行,使其显示为:
Address = x.Address?.FirstLine + " " + x.Address?.SecondLine,
当我在tmp
中输入一个空条目时,该代码即可正常工作。
我不理解这是因为tmp
上的Address属性已经允许空值,而视图模型上的Address属性已经允许空值,所以,为什么更改行突然不返回错误?
此外,我不必做x.Address?.FirstLine?
的原因是因为这是一个字符串,并且字符串已经可以为空吗?
答案 0 :(得分:5)
在这种特殊情况下,当您尝试访问父对象本身为null的属性时,将导致null引用异常。
x.Address.FirstLine
即在您的情况下,地址为空。
这与您要设置的内容(即目标视图模型)无关。
这有效的原因:
x.Address?.FirstLine
..是因为“在后台”首先检查Address
是否为空。如果不是,则返回FirstLine
;如果不是,则返回null。在语义上等效于:
if (x.Address == null)
{
return null;
}
else
{
return x.Address.FirstLine;
}
这是有关?的介绍的博客文章。 C#中的运算符以了解一些背景知识:https://blogs.msdn.microsoft.com/jerrynixon/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator/
答案 1 :(得分:2)
我不明白这是因为tmp上的Address属性已经允许空值,而视图模型上的Address属性已经允许空值,所以,为什么更改行突然不返回错误?
您正在混合保存数据和加载数据。将数据保存到数据库时,out <- boxplot.stats(train$TEAM_FIELDING_E)$out
train %>%
mutate(TEAM_FIELDING_E = if_else(TEAM_FIELDING_E %in% out, mean(TEAM_FIELDING_E[!(TEAM_FIELDING_E %in% out)]), TEAM_FIELDING_E))
是可以接受的,但是当您尝试使用数据时,null
是不可接受的。
null conditional运算符(null
)允许您“缩短” ?.
语句,这类似于:
if
虽然与您的问题无关,但是您使用的代码效率极低,当您可以直接从数据库中获取这些属性时,您正在加载2个表以获取一些属性:
Address = x.Address?.FirstLine + " " + x.Address?.SecondLine,
string Address = "";
if (x.Address != null)
{
Address += x.Address.FirstLine;
}
// ....
答案 2 :(得分:2)
x.Address?.FirstLine
,其中?
是null传播运算符,这意味着如果x.Address
是null
,请为null
设置FirstLine
。
无效传播等效代码
if (x.Address == null)
return null
else
return x.Address.FirstLine
所有引用类型变量都可以为空。因此,将null分配给引用类型始终有效。
string
是您的示例中的引用类型。因此不会出现错误,因为string x = null
有效
答案 3 :(得分:1)
您的问题不是Address
为空,而是试图将其分配给另一个允许null的属性,而是您试图以空值访问.FirstLine
。 / p>
如果Address
为空,那么您要使用的.FirstLine
等效于null.FirstLine
,这是行不通的。没有什么不能容纳东西。
您正在使用的?
表示法仅会影响Address
,基本上是说Address
是否 NOT null给我{{ 1}},如果它为null,请给我null。