C#coalesce operator抛出

时间:2012-03-28 14:48:45

标签: c# string c#-4.0 null-coalescing-operator null-coalescing

我有一个带字符串属性的类。我在读取它时使用coalesce运算符,因为它可能为null,但它仍然会抛出一个NullRefrenceExeption。

string name = user.Section.ParentSection.Name ?? string.Empty;

更具体地说,它的“.ParentSection”是null,因为它甚至没有“.name”?如果是这种情况,我应该先用if块测试“.ParentSection”吗?

我假设有一些关于Coalesce运算符的东西,我不明白,希望有人可以了解这里出了什么问题。

9 个答案:

答案 0 :(得分:7)

  

更具体地说,它的“.ParentSection”是空的   因为它甚至没有“.name”?

  

如果是这种情况,我应首先使用if测试“.ParentSection”   方框?

答案 1 :(得分:4)

您需要检查SectionParentSection是否为空。您可以为此使用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)

您需要检查useruser.Sectionuser.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)

可能是useruser.Sectionuser.Section.ParentSection是空值。

??运算符不会阻止以下检查:

if (user != null && user.Section != null && user.Section.ParentSection != null){

确保字符串属性的所有内容都有效且存在,然后您可以使用??。无论您尝试多少次,都无法致电(null).Name

答案 6 :(得分:0)

是的,在检查Section

之前,您需要检查ParentSectionName是否为空

答案 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。