Understanding and Using ? (nullable) in C#
In C#, ?
is the symbol used to declare a variable as nullable, meaning it can hold a null
value.
? (nullable) declaration
string text1 = null;
string? text2 = null;
Both variables are null
, but when you call text1.ToString()
, a runtime null reference exception will occur.
This happens because text1
is null
, meaning it points to nothing. Trying to access .ToString()
on a null
variable results in an exception.
To put it into words, asking someone who has no thoughts, "What should we have for lunch?" is similar. The person doesn't have any thoughts, so asking them anything at all would be an error.
On the other hand, text2
has been declared with ?
, which tells the compiler, "This variable might be null
." However, just informing the compiler doesn't automatically prevent exceptions. You still need to handle it explicitly.
?. (null-conditional operator)
Thus, ?
(nullable) declaration and ?.
(null-conditional operator) must be differentiated.
Console.WriteLine(text2?.ToString());
In this code, ?.ToString()
ensures that if text2
is null
, .ToString()
is not called, and null
is returned. So, no exception is thrown because the operator ensures that the member or function is not accessed when the object is null
.
Using the earlier analogy, ?.
indicates "I might sometimes not have any thoughts." This lets the other person know that they can distinguish between when you are thinking and when you are not. If they know you're thinking, they can ask, "What are you thinking about?" But if they realize you're not thinking, they'll avoid asking you.
?? (null-coalescing operator)
When a variable declared with ?
is null
, you can either handle it or ignore it. In such cases, the ??
(null-coalescing operator) is used for additional processing.
string text = null;
string result = text ?? "empty"; // If text is null, assign "empty"
Console.WriteLine(result); // Output: empty
However, it is often safer to use ?
(nullable) with ??
.
string? text = null;
// If text is not null, call ToString(), otherwise use "empty"
string result = text?.ToString() ?? "empty";
Console.WriteLine(result); // Output: empty
By properly using ?
, ?.
, and ??
, you can safely handle null
values.