我有一个带字符串属性的类。我在读取它时使用coalesce运算符,因为它可能为null,但它仍然会抛出一个NullRefrenceExeption。
string name = user.Section.ParentSection.Name ?? string.Empty;
更具体地说,它的“.ParentSection”是null,因为它甚至没有“.name”?如果是这种情况,我应该先用if块测试“.ParentSection”吗?
我假设有一些关于Coalesce运算符的东西,我不明白,希望有人可以了解这里出了什么问题。
答案 0 :(得分:7)
更具体地说,它的“.ParentSection”是空的 因为它甚至没有“.name”?
是
如果是这种情况,我应首先使用if测试“.ParentSection” 方框?
是
答案 1 :(得分:4)
您需要检查Section
和ParentSection
是否为空。您可以为此使用if语句或编写如下的扩展方法:
public static class MaybeMonad
{
public static TOut With<TIn, TOut>(this TIn input, Func<TIn, TOut> evaluator)
where TIn : class
where TOut : class
{
if (input == null)
{
return null;
}
else
{
return evaluator(input);
}
}
}
您可以像这样使用此方法:
string name = user.With(u => u.Section)
.With(s => s.ParentSection)
.With(p => p.Name) ?? string.Empty;
我认为它比带有很多&&
的if语句更清晰。
进一步阅读:http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
答案 2 :(得分:3)
您需要检查user
,user.Section
或user.Section.ParentSection
是否为空,然后才能在user.Section.ParentSection
的属性上使用空合并运算符。
答案 3 :(得分:3)
如果访问的任何对象为null
,则嵌套属性访问不安全,这会抛出NullReferenceException
。您必须显式测试外部对象是否为空。
E.g:
string name = string.Empty;
if(user!=null && user.Section!=null && user.Section.ParentSection !=null)
name = user.Section.ParentSection.Name ?? string.Empty;
一般情况下,我会尝试避免对属性进行嵌套访问,但是您违反了Law of Demeter。一些重构可能首先使这不必要。
答案 4 :(得分:2)
??
运算符检查左侧是否为空,如果是,则返回右侧(如果不是左侧)。
在您的情况下,左侧是对象user.Section.ParentSection
中的“名称”属性,这是null。
在这些情况下,要么考虑什么可能是null或做这样的事情:
string name = user == null
|| user.Section == null
|| user.ParentSection == null
|| user.Section.ParentSection.Name == null
? string.Empty
: user.Section.ParentSection.Name;
(是的,我知道这很难看)
答案 5 :(得分:1)
可能是user
或user.Section
或user.Section.ParentSection
是空值。
??
运算符不会阻止以下检查:
if (user != null && user.Section != null && user.Section.ParentSection != null){
确保字符串属性的所有内容都有效且存在,然后您可以使用??
。无论您尝试多少次,都无法致电(null).Name
。
答案 6 :(得分:0)
是的,在检查Section
ParentSection
或Name
是否为空
答案 7 :(得分:0)
最好做这样的事情:
if(user!=null && user.Section!=null && user.Section.ParentSection!=null)
{
string name = user.Section.ParentSection.Name ?? string.Empty;
}
答案 8 :(得分:0)
null coalescing运算符采用如下语句:
a = b ?? c;
这说的是“评估b;如果它具有非空值,则将其分配给a。否则将c的值赋给”。
但是在你的 b中你正在使用一个用户对象,该对象可能是null,其中一个section对象可能为null,其父段属性可能为null,其name属性为可能是null。如果您想检查所有这些(通常是您应该),那么您可以执行以下操作:
string name = string.Empty;
if (user != null &&
user.Section != null &&
user.Section.ParentSection != null)
{
name = user.Section.ParentSection.Name ?? string.Empty;
}
一旦IF检查失败,它将不会进一步检查,因此当您假设某个对象存在然后尝试访问其中一个属性时,您不会收到NullReferenceException。