C# Null propagating operator / Conditional access expression & if blocks

The Null propagating operator / Conditional access expression coming in c#-6.0 looks like quite a handy feature. But I'm curious if it will help solve the problem of checking if a child member is not null and then calling a Boolean method on said child member inside an if block:

  public class Container<int>{
       IEnumerable<int> Objects {get;set;}
  }

  public Container BuildContainer()
  { 
      var c = new Container();

      if (/* Some Random Condition */)
         c.Objects = new List<int>{1,2,4};
  }

  public void Test()
  {
      var c = BuildContainer();

      //Old way
      if ( null != c && null != c.Objects && c.Objects.Any())
         Console.Write("Container has items!");


      //C# 6 way?
      if (c?.Object?.Any())
          Console.Write("Container has items!");
  }

Will c?.Object?.Any() compile? If the propagating operator short circuits (I assume that's the right term) to null then you have if (null) , which isn't valid.

Will the C# team address this concern or am I missing the intended use case for the null propagating operator?


It won't work this way. You can just skip the explanation and see the code below :)

As you know ?. operator will return null if a child member is null. But what happens if we try to get a non-nullable member, like the Any() method, that returns bool ? The answer is that the compiler will "wrap" a return value in Nullable<> . For example, Object?.Any() will give us bool? (which is Nullable<bool> ), not bool .

The only thing that doesn't let us use this expression in the if statement is that it can't be implicitly casted to bool . But you can do comparison explicitly, I prefer comparing to true like this:

if (c?.Object?.Any() == true)
    Console.Write("Container has items!");

Thanks to @DaveSexton there's another way:

if (c?.Object?.Any() ?? false)
    Console.Write("Container has items!");

But as for me, comparison to true seems more natural :)


Null-conditional operator would return null or the value at the end of expression. For value types It will return result in Nullable<T> , so in your case it would be Nullabe<bool> . If we look at the example in the document for Upcoming Features in C# (specified here), it has an example:

int? first = customers?[0].Orders.Count();

In the above example, instead of int , Nullable<int> would be returned. For bool it will return Nullable<bool> .

If you try the following code in Visual Studio "14" CTP:

Nullable<bool> ifExist = c?.Objects?.Any();

The result of the above line would be a Nullable<bool> / bool? . Later you can do the comparison like:

Using null-coalescing operator ??

 if (c?.Object?.Any() ?? false)

Using Nullable<T>.GetValueOrDefault Method

if ((c?.Objects?.Any()).GetValueOrDefault())

Using comparison against true

if (c?.Objects?.Any() == true)
链接地址: http://www.djcxy.com/p/2102.html

上一篇: 为什么在做case时避免使用string.ToLower()

下一篇: C#空传播运算符/条件访问表达式和if块