I recently found that we can use ?? operator to check nulls. Please check the below code samples:
var res = data ?? new data();
This is exactly similar to
var res = (data==null) ? new data() : data ;
I checked my whole project source repository and some of other open source projects. And this ??
operator never been used.
I just wondering is there any reason behind this, like performance problems or something?
EDIT:
I just updated my sample code based on the comments from recursive & Anton. Its a mistake in careless. :(
The null coalesce operator is much clearer when checking for null, that is its main purpose. It can also be chained.
object a = null; object b = null; object c = new object(); object d = a ?? b ?? c; //d == c.
While that operator is limited to null checking, the ternary operator is not. For example
bool isQuestion = true; string question = isQuestion ? "Yes" : "No";
I think people just aren't aware of the null coalesce operator so they use the ternary operator instead. Ternary existed before C# in most C style languages so if you don't know C# inside and out and/or you programmed in another language, ternary is a natural choice. If you are checking for null though, use the null coalesce operator, it is designed for that, and the IL is slightly optimized (compare ?? to an if then else).
Here is an example comparing the use of each
object a = null; object b = null; object c = null; object nullCoalesce = a ?? b ?? c; object ternary = a != null ? a : b != null ? b : c; object ifThenElse; if (a != null) ifThenElse = a; else if (b != null) ifThenElse = b; else if (c != null) ifThenElse = c;
First, just look at the syntax for null coalesce, it is way clearer. Ternary is really confusing. Now lets look at the IL
Null Coalesce Only
.entrypoint .maxstack 2 .locals init ( [0] object a, [1] object b, [2] object c, [3] object nullCoalesce) L_0000: ldnull L_0001: stloc.0 L_0002: ldnull L_0003: stloc.1 L_0004: newobj instance void [mscorlib]System.Object::.ctor() L_0009: stloc.2 L_000a: ldloc.0 L_000b: dup L_000c: brtrue.s L_0015 L_000e: pop L_000f: ldloc.1 L_0010: dup L_0011: brtrue.s L_0015 L_0013: pop L_0014: ldloc.2 L_0015: stloc.3 L_0016: ldloc.3 L_0017: call void [mscorlib]System.Console::WriteLine(object) L_001c: ret
Ternary Only
.entrypoint .maxstack 2 .locals init ( [0] object a, [1] object b, [2] object c, [3] object ternary) L_0000: ldnull L_0001: stloc.0 L_0002: ldnull L_0003: stloc.1 L_0004: newobj instance void [mscorlib]System.Object::.ctor() L_0009: stloc.2 L_000a: ldloc.0 L_000b: brtrue.s L_0016 L_000d: ldloc.1 L_000e: brtrue.s L_0013 L_0010: ldloc.2 L_0011: br.s L_0017 L_0013: ldloc.1 L_0014: br.s L_0017 L_0016: ldloc.0 L_0017: stloc.3 L_0018: ldloc.3 L_0019: call void [mscorlib]System.Console::WriteLine(object) L_001e: ret
If Then Else Only
.entrypoint .maxstack 1 .locals init ( [0] object a, [1] object b, [2] object c, [3] object ifThenElse) L_0000: ldnull L_0001: stloc.0 L_0002: ldnull L_0003: stloc.1 L_0004: newobj instance void [mscorlib]System.Object::.ctor() L_0009: stloc.2 L_000a: ldloc.0 L_000b: brfalse.s L_0011 L_000d: ldloc.0 L_000e: stloc.3 L_000f: br.s L_001a L_0011: ldloc.1 L_0012: brfalse.s L_0018 L_0014: ldloc.1 L_0015: stloc.3 L_0016: br.s L_001a L_0018: ldloc.2 L_0019: stloc.3 L_001a: ldloc.3 L_001b: call void [mscorlib]System.Console::WriteLine(object) L_0020: ret
IL isn't one of my strong points, so maybe someone can edit my answer and expand on it. I was going to explain my theory, but I'd rather not confuse myself and others. The number of LOC is similar for all three, but not all IL operators take the same length of time to execute.
The ?? operator (also known as the null-coalescing operator) is less known than the ternary operator, as it made its debut with .NET 2.0 and Nullable Types. Reasons for not using it probably include not begin aware that it exists, or being more familiar with the ternary operator.
That said, checking for null is not the only thing the ternary operator is good for, so it's not a replacement for it as such, more like a better alternative for a very specific need. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With