It can be very useful when flattening a hierarchy and/or mapping objects. Instead of:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
It can be written like (same logic as above)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
DotNetFiddle.Net Working Example.
(the ?? or null-coalescing operator is different than the ? or null conditional operator).
It can also be used out side of assignment operators with Action. Instead of
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
It can be simplified to:
myAction?.Invoke(TValue);
DotNetFiddle Example:
using System;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
Result:
Test 2
Basically, I have applied ?. operator after Model as well. I am trying to know that whether it can be applied directly to the model or does it only work with the navigation properties?
The ? or null conditional operator operators on the left value, regardless of the type of value. And the compiler doesn't care what the value is on the right. It's simple compiler magic (meaning it does something you can already do, just in a simplified why).
For example
var a = model?.Value;
is the same as saying
var a = model == null ? null : model.Value;
In the second case the evaluation of checking for null has no associate with the value returned. The null conditional operator basically just always return null if the left value is null.
The type of member (Method, Field, Property, Constructor) .Value
is irrelevant.
The reason your DotNetFiddle example doesn't work is because the compiler being use for the .Net 4.7.2
isn't compatible with the c# version that support the null conditional operator. Changing it to .Net 5, works:
https://dotnetfiddle.net/7EWoO5