The draft spec for Pattern Matching in C# contains the following code example:
Type? v = x?.y?.z;
if (v.HasValue) {
var value = v.GetValueOrDefault();
// code using value
}
I understand that Type? indicates that Type is nullable, but assuming x, y, and z are locals, what does x?.y?.z mean?
Be aware that this language feature is only available in C# 6 and later.
It's effectively the equivalent of:
x == null ? null
: x.y == null ? null
: x.y.z
In other words, it's a "safe" way to do x.y.z, where any of the properties along the way might be null.
Also related is the null coalescing operator (??), which provides values to substitute for null.
It is Null-propagating operator / Null-Conditional Operator ?. a new proposed feature in C# 6.0
x?.y?.z means
first, check if x is not null, then check y otherwise return null,
second, when x is not null then check y, if it is not null then return z otherwise return null.
The ultimate return value will be z or null.
Without this operator if x is null, then accessing x.y would raise a Null Reference Exception, the Null-Conditional operator helps to avoid explicitly checking for null.
It is a way to avoid Null Reference Exception.
See: Getting a sense of the upcoming language features in C#
8 - Null-conditional operators
Sometimes code tends to drown a bit in null-checking. The
null-conditional operator lets you access members and elements only
when the receiver is not-null, providing a null result otherwise:
int? length = customers?.Length; // null if customers is null
this.SlimShadies.SingleOrDefault(s => s.IsTheReal)?.PleaseStandUp();
Basically.
Related
on the c# 6.0 tutorial it says: Lifted equality operators handle nulls just like reference types do. This means two null values are equal:
Console.WriteLine ( null == null); // True
Console.WriteLine((bool?)null == (bool?)null); // True
While I tried first express in IDE, it won't compile, complains
Not sure what is the reason?
When I write this:
ReferenceEquals(x, null)
Visual studio suggests that the
null check can be simplified.
and simplifies it to
x is null
Are those really the same?
I noticed a lot of answers specifying that x == null, x is null, and ReferenceEquals(x, null) are all equivalent - and for most cases this is true. However, there is a case where you CANNOT use x == null as I have documented below:
Note that the code below assumes you have implemented the Equals method for your class:
Do NOT do this - the operator == method will be called recursively until a stack overflow occurs:
public static bool operator ==(MyClass x1, MyClass x2)
{
if (x1 == null)
return x2 == null;
return x1.Equals(x2)
}
Do this instead:
public static bool operator ==(MyClass x1, MyClass x2)
{
if (x1 is null)
return x2 is null;
return x1.Equals(x2)
}
Or
public static bool operator ==(MyClass x1, MyClass x2)
{
if (ReferenceEquals(x1, null))
return ReferenceEquals(x2, null);
return x1.Equals(x2)
}
Are those really the same?
Semantically yes (assuming x is not a value type). You're doing a null check which is the same for all reference types.
Implementation: no. x == null or x is null will be directly implemented as IL instructions but Object.ReferenceEquals(x, null) will be a method call.1
Also note if the type of x has overridden operator == then x == null may not be equivalent (changing the semantics of null checks in an operator overload is, at best, poor code because no one expects such a semantic change).
1 Of course the optimiser could recognise this and just output the IL, you'll need to look at the IL to confirm this.
I realize that I'm supre-late to the party and that answers have been given, but I feel the need to summarize a bit since this is a thing I search for every 8-12 months or so and I'd like to have an explanation I can understand (hopefully, if it gets posted)..
1. ReferenceEquals(a,b)
This is the tried and tested method to perform a safe reference equality comparison. It basically performs (object)a == (object)b (or something to that effect) and has the advantages that its use is instantly recognizable and it can't be overridden.
2. a == b
This method is the one that feels "natural" to most people (since most comparison done throughout C# will be done with this operator).
Default behaviour on reference types should be correct. However, this can be overloaded, which can lead to unexpected results (imagining a failed implementation of the operator overload).
Like #mdebeus said, an additional risk (however marginal even for a competent monkey that read a primer on C#) is causing a StackOverflowException. This can appear when overloading == and != and using the operators inside the method itself.
3. a is b
OK so this is shiny new sort of sugary thing that we get. Microsoft describes is in this case with:
The is operator checks if the runtime type of an expression result is compatible with a given type.
[...]
The E is T expression returns true if the result of E is non-null and
can be converted to type T by a reference conversion, a boxing
conversion, or an unboxing conversion; otherwise, it returns false.
The is operator doesn't consider user-defined conversions.
(read a complete description here)
The short of it is that this will return true if a can be converted through b via boxing, unboxing or covariance.
As you would expect, this works very well against null.
All in all, as a personal note, although is makes things shorter and prettier for null check in equality overloading, I think I'll would still use ReferenceEquals, simply because I'm a control-freak and there is at least a part of how is works that worries me when it comes to cases of covariance.
They mean the same in this case, yes. Most would use x == null though.
I guess ReferenceEquals could be little bit confusing because actually null is a literal that means no reference at all. How can any reference be equal to no reference?
Note that x is null is only allowed with C#7 and it's pattern matching feature. Normally you use is to check if x is a compatible type but null is not a type. So this is a bit confusing as well.
That's why i prefer x == null
var a = b?.c.d;
Shouldn't this expression always give a compile error? If b is null, the null value is propagated through so c will also be null and thus also need this operator. In my understanding usage of this operator in an expression spreads viral.
But neither Visual Studio 2015 nor Resharper says anything to me, am I missing something here?
The operator is just syntactic sugar for this:
MyType a = b == null ?
null:
b.c.d;
Why this should throw a compile-error is unclear to me.
If b is null, the null value is propagated through so c will also be null and thus also need this operator
This isn´t true. Actually when b is null c doesn´t even exist as there´s no instance on which that member could exist. So in short the operator just returns null and omits evaluating c or even d any further.
This operator does short circuit and returns null in case of b is null.
var a = b == null ? null : b.c.d
This is what that statement would look like in the old way, the ?. operator doesn't look deeper when what is before it is null, it just returns null, you WILL however get an error where b is defined but b.c == null since you didn't write as var a = b?.c?.d.
Note that:
var a1 = b?.c.d;
is entirely different from:
var a2 = (b?.c).d;
It is not very easy to explain in short how the unary operator ?. works (yes, unary!). But the idea is that the rest of the "chain" of "operations" is skipped if the expression before ?. is null.
So for a1, you get a null of the compile-time type carried by member d (or Nullable<> of that type if necessary) whenever b happens to be null. When b happens to be non-null, you get the same as b.c.d which may fail if b.c is null.
But a2 is quite different. It will always blow up if b is null, because then the parenthesis (b?.c) will be a null reference, and the next . operator will lead to NullReferenceException. (I am assuming here that c has a reference-type at compile-time.)
So do not think there is a kind of "left-associativity" that makes b?.c.d equivalent to (b?.c).d!
You can find a link to the preliminary C# Language Specification in this answer in another thread; they mention Null-conditional operator as an unary operator in § 7.7.1.
Hey Everyone I thought that this code would be valid in any case because it is casted to bool
parameter.Request?.InnerData?.Any() == false
Instead this code is casted to type bool?
Can tell me someone why? (this is main question)
Is there better way to check this instead of something like this?
var isThereInnerData = parameter.Request?.InnerData?.Any();
if (isThereSegments == null || isThereSegments == false)
With a null-conditional operator, null propagates. You can't end up with a non-nullable type if you use the null-conditional operator - this is the same behaviour in languages where null operations are "safe" by default (SQL, Objective-C, ...). So the result is default(bool?) if parameter.Request is null, or parameter.Request.InnerData is null. Otherwise, you get true or false, but by using the null-conditional operator you already assume the result can in fact be null, so the compiler must accomodate that. Since bool can't be null, it is changed into a nullable bool (bool?).
The solution is simple - think about what logical value a null should have, and use that:
if (parameter.Request?.InnerData?.Any() ?? true)
In this case, a null value is interpreted as true, but you can also use false if you want. Alternatively, instead of the null-coalescing operator, you can use GetValueOrDefault, whatever feels better for you.
Here is what C# reference says about ?. operator:
x?.y – null conditional member access. Returns null if the left hand
operand is null.
Since at compile time the compiler doesn't knows whether the expression will evaluate to a non-null value, the compiler infers the type as Nullable<bool>
Since you are chaining the ?. operator this line from msdn documentation is relevant too:
The null-condition operators are
short-circuiting. If one operation in a chain of conditional member
access and index operation returns null, then the rest of the chain’s
execution stops. Other operations with lower precedence in the
expression continue. For example, E in the following always executes,
and the ?? and == operations execute.
bool is a value type and per default cannot be compared with null. C# converts your return value to bool? to give you the option to support both.
The Nullable<T> type is defined as a struct. In .Net, you can't assign null to a struct because structs are value types that cannot be represented with null (with the exception of Nullable<T>).
int i = null; // won't compile - we all know this
int? i = null; // will compile, and I'm glad it does, and it should compile, but why?
How did Nullable<T> become an exception to the rule "You can't assign null to a value type?" The decompiled code for Nullable<T> offers no insights as of to how this happens.
How did Nullable<T> become an exception to the rule "You can't assign null to a value type?"
By changing the language, basically. The null literal went from being "a null reference" to "the null value of the relevant type".
At execution time, "the null value" for a nullable value type is a value where the HasValue property returns false. So this:
int? x = null;
is equivalent to:
int? x = new int?();
It's worth separating the framework parts of Nullable<T> from the language and CLR aspects. In fact, the CLR itself doesn't need to know much about nullable value types - as far as I'm aware, the only important aspect is that the null value of a nullable value type is boxed to a null reference, and you can unbox a null reference to the null value of any nullable value type. Even that was only introduced just before .NET 2.0's final release.
The language support mostly consists of:
Syntactic sugar in the form of ? so int? is equivalent to Nullable<int>
Lifted operators
The changed meaning of null
The null-coalescing operator (??) - which isn't restricted to nullable value types