The new C# 6.0 null-conditional operator is a handy vehicle for writing more concise and less convoluted code. Assuming one has an array of customers, then you could get null instead of a length if customers
is null using this (examples from MSDN):
int? length = customers?.Length;
Similarly you could get null instead of a customer with this:
Customer first = customers?[0];
And for a more elaborate expression, this yields null if customers
is null, the first customer is null, or the first customer's Orders
object is null:
int? count = customers?[0]?.Orders?.Count();
But then there is the interesting case of the non-existent customer that the null-conditional operator does not seem to address. We saw above that a null customer is covered, i.e. if an entry in the customers
array is null. But that is quite distinct from a non-existent customer, e.g. looking for customer 5
in a 3-element array or customer n
in a 0-element list. (Note that the same discussion applies to Dictionary lookup as well.)
It seems to me that the null-conditional operator is focused exclusively on negating the effects of a NullReferenceException; IndexOutOfRangeException or KeyNotFoundException are alone, exposed, cowering in the corner, and needing to fend for themselves! I submit, that in the spirit of the null-conditional operator, it should be able to handle those cases as well... which leads to my question.
Did I miss it? Does the null-conditional provide any elegant way to truly cover this expression...
customers?[0]?.Orders?.Count();
...when there is no zeroth element?
The null-conditional operators are short-circuiting. That is, if one operation in a chain of conditional member or element access operations returns null , the rest of the chain doesn't execute.
In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned. This code returns the name of an item or the default name if the item is null. As you can see, this operator is a handy tool when working with the null-conditional operator.
No, because it is a null-conditional operator, not an indexoutofrange-conditional operator and is merely syntactic sugar to something like the following:
int? count = customers?[0]?.Orders?.Count(); if (customers != null && customers[0] != null && customers[0].Orders != null) { int count = customers[0].Orders.Count(); }
You can see that if there is no zeroth customer, you will get your regular IndexOutOfRangeException
.
One way you could work around it is to have an extension method that checks for the index and returns null if it doesn't exist:
public static Customer? GetCustomer(this List<Customer> customers, int index) { return customers.ElementAtOrDefault(index); // using System.Linq }
Then your check could be:
int? count = customers?.GetCustomer(0)?.Orders?.Count();
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