C# tutorials > Modern C# Features > C# 6.0 and Later > How does the null-conditional operator (`?.`) work and why is it useful?
How does the null-conditional operator (`?.`) work and why is it useful?
The null-conditional operator (`?.`) is a feature introduced in C# 6.0 that allows you to access members and elements of an object only if that object is not null. It provides a concise way to handle null checks and avoid `NullReferenceException` errors, making your code cleaner and more readable. This operator is especially useful when working with object graphs or properties that might be null.
Basic Syntax and Functionality
The `?.` operator checks if the object on the left side is null. If it is null, the entire expression evaluates to null. If it's not null, it proceeds to access the member on the right side. In the example above, if `person` is null, then `person?.Address?.City` evaluates to null. If `person` is not null but `person.Address` is null, then the expression also evaluates to null. Only if both `person` and `person.Address` are not null, the `City` property will be accessed.
string name = person?.Address?.City;
Avoiding NullReferenceException
Without the null-conditional operator, you would need to use nested `if` statements to check for null at each level of the object graph. The `?.` operator simplifies this process, making the code more concise and easier to read. The example shows how the null-conditional operator achieves the same result as the verbose `if` statement approach. It significantly reduces boilerplate code associated with null checks.
string city;
if (person != null && person.Address != null)
{
city = person.Address.City;
}
else
{
city = null;
}
// Equivalent using null-conditional operator:
string city2 = person?.Address?.City;
Concepts Behind the Snippet
The core concept behind the null-conditional operator is to short-circuit the evaluation of an expression when a null value is encountered. This prevents the `NullReferenceException` and allows for more graceful handling of potentially missing data. It embodies the principle of null-safety, making code more robust against unexpected null values.
Real-Life Use Case
Imagine a scenario where you're fetching data from a database or an external API. The data might be incomplete, and some properties might be null. In this example, we are getting the last name of a Company's CEO. The `GetCompany()` method might return null, and even if the `Company` is not null, the `CEO` property might be null. The null-conditional operator allows us to safely access the `LastName` property and provide a default value (`"N/A"`) using the null-coalescing operator (`??`) if any of the preceding properties are null. This prevents a `NullReferenceException` and provides a reasonable fallback value.
public class Company
{
public string Name { get; set; }
public Employee CEO { get; set; }
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Company company = GetCompany(); // Assume GetCompany() can return null
string ceoLastName = company?.CEO?.LastName ?? "N/A";
Console.WriteLine($"CEO Last Name: {ceoLastName}");
Null-Conditional Operator with Indexers
The null-conditional operator can also be used with indexers, such as accessing elements in an array or list. In this case, if `names` is null, the `firstItem` will be null. The null coalescing operator provides a default message, if `names` is null.
string[] names = GetNames(); // Assume GetNames() can return null
string firstItem = names?[0]; // Safely access the first element
Console.WriteLine($"First Name: {firstItem ?? "No names found."}");
Best Practices
Interview Tip
When discussing the null-conditional operator in an interview, highlight its role in improving code readability and reducing the risk of `NullReferenceException`. Mention that it is a more concise alternative to traditional null checks and that it seamlessly integrates with other operators like the null-coalescing operator. Also, be prepared to discuss scenarios where it might not be appropriate (e.g., when a `NullReferenceException` is actually the desired behavior to signal an error).
When to Use Them
The null-conditional operator should be used whenever you are working with objects or properties that might be null, especially in situations involving object graphs or data from external sources. It's particularly useful when accessing nested properties, array elements, or dictionary values. However, consider carefully whether swallowing a `NullReferenceException` is the right approach. Sometimes you *want* the exception to be thrown, to indicate that something has gone seriously wrong.
Memory Footprint
The null-conditional operator itself doesn't significantly impact the memory footprint of your application. It's primarily a syntactic sugar that simplifies null checks. The memory usage is determined by the objects and properties involved in the expression, not by the operator itself.
Alternatives
Before C# 6.0, the common alternative was using nested `if` statements to check for null at each level. Another alternative is using extension methods to provide null-safe access to properties. For example, you could create an extension method that returns a default value if the property is null. However, the null-conditional operator is generally considered the most concise and readable option.
Pros
Cons
FAQ
-
What happens if I use the null-conditional operator on a value type?
The null-conditional operator works with nullable value types (e.g., `int?`, `DateTime?`). If the nullable value type has a value, it proceeds as normal. If it is null, the expression evaluates to null. -
Can I use the null-conditional operator with methods?
Yes, you can use the null-conditional operator to call methods on an object only if the object is not null. For example: `person?.GetFullName()`. -
Is the null-conditional operator available in older versions of C#?
No, the null-conditional operator was introduced in C# 6.0. You'll need to use a compiler that supports C# 6.0 or later to use this feature.