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块