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

痴心易碎 提交于 2019-11-26 11:36:05

问题


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?


回答1:


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 :)




回答2:


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)


来源:https://stackoverflow.com/questions/25666993/c-sharp-null-propagating-operator-conditional-access-expression-if-blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!