?. operator and
?[...] operator are called the null-conditional operator. It is also sometimes referred to by other names such as the safe navigation operator.
This is useful, because if the
. (member accessor) operator is applied to an expression that evaluates to
null, the program will throw a
NullReferenceException. If the developer instead uses the
?. (null-conditional) operator, the expression will evaluate to null instead of throwing an exception.
Note that if the
?. operator is used and the expression is non-null,
. are equivalent.
var teacherName = classroom.GetTeacher().Name; // throws NullReferenceException if GetTeacher() returns null
classroom does not have a teacher,
GetTeacher() may return
null. When it is
null and the
Name property is accessed, a
NullReferenceException will be thrown.
If we modify this statement to use the
?. syntax, the result of the entire expression will be
var teacherName = classroom.GetTeacher()?.Name; // teacherName is null if GetTeacher() returns null
classroom could also be
null, we could also write this statement as:
var teacherName = classroom?.GetTeacher()?.Name; // teacherName is null if GetTeacher() returns null OR classroom is null
This is an example of short-circuiting: When any conditional access operation using the null-conditional operator evaluates to null, the entire expression evaluates to null immediately, without processing the rest of the chain.
When the terminal member of an expression containing the null-conditional operator is of a value type, the expression evaluates to a
Nullable<T> of that type and so cannot be used as a direct replacement for the expression without
bool hasCertification = classroom.GetTeacher().HasCertification; // compiles without error but may throw a NullReferenceException at runtime bool hasCertification = classroom?.GetTeacher()?.HasCertification; // compile time error: implicit conversion from bool? to bool not allowed bool? hasCertification = classroom?.GetTeacher()?.HasCertification; // works just fine, hasCertification will be null if any part of the chain is null bool hasCertification = classroom?.GetTeacher()?.HasCertification.GetValueOrDefault(); // must extract value from nullable to assign to a value type variable
You can combine the null-conditional operator with the Null-coalescing Operator (
??) to return a default value if the expression resolves to
null. Using our example above:
var teacherName = classroom?.GetTeacher()?.Name ?? "No Name"; // teacherName will be "No Name" when GetTeacher() // returns null OR classroom is null OR Name is null