C#空传播算子/条件访问表达式&如果块C#空传播算子/条件访问表达式&如果块(C# Null pro

2019-05-12 09:45发布

该空传播运营商/条件接入表达在未来的C#-6.0看起来像一个非常方便的功能。 不过我很好奇,如果这将有助于解决检查,如果一个子成员不为空,然后调用布尔方法的问题上说的,如果块内子成员:

  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!");
  }

c?.Object?.Any()编译? 如果传播运营商短路(我认为这是正确的术语)为空,那么你必须if (null) ,这是无效的。

将C#团队解决这一问题还是我失去了对空传播经营者预期使用情况?

Answer 1:

它不会以这种方式工作。 你可以跳过的解释,看看下面的代码:)

正如你知道的?. 如果一个子成员为空操作将返回null。 但是,如果我们试图得到一个非空的成员一样,会发生什么Any()方法,返回bool ? 答案是编译器将在“包装”的返回值Nullable<> 例如, Object?.Any()将给我们bool? (这是Nullable<bool> ),而不是bool

这并不让我们在使用这种表达的唯一的事情if声明的是,它不能被隐式强制转换为bool 。 但是你可以做的比较明确的,我更喜欢比较true是这样的:

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

由于@DaveSexton有另一种方式:

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

但对我来说,比较true ,似乎更自然:)



Answer 2:

空条件运算符将返回null在表达式的结束或价值。 对于值类型它将返回结果Nullable<T>所以你的情况这将是Nullabe<bool> 。 如果我们看一下文档中的例子在C#即将发布的功能 (指定位置 ),它有一个例子:

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

在上述例子中,代替intNullable<int>将被返回。 对于bool它将返回Nullable<bool>

如果您尝试下面的代码的Visual Studio“14” CTP :

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

上面的行的结果将是一个Nullable<bool> / bool? 。 后来,你可以不喜欢的比较:

使用空合并运算符?

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

使用Nullable<T>.GetValueOrDefault方法

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

使用针对比较true

if (c?.Objects?.Any() == true)


文章来源: C# Null propagating operator / Conditional access expression & if blocks