I am using this solution to do a chained null check in my code
Cleaner way to do a null check in C#?
I was just wondering cant we make it like this.
bool returnValue = Helper.IsNull(nullPerson.contact.address.city);
Wouldn't that be even more cleaner ?
I tried writing such a generic function
public static bool IsNull<T>(this T rootObj)
{
var visitor = new IsNullExpressionVisitor();
//...
//...
}
but then I got stuck on how to make expression out of this rootObject.
If you have implemented layering in your project, good place to do null checks are the layers that receives data externally. Like for example: the controllers, because it receives data from the user... or the gateways because it receives data from repositories.
We can get rid of all those null checks by utilizing the Java 8 Optional type. The method map accepts a lambda expression of type Function and automatically wraps each function result into an Optional . That enables us to pipe multiple map operations in a row. Null checks are automatically handled under the hood.
Java 8 introduced an Optional class which is a nicer way to avoid NullPointerExceptions. You can use Optional to encapsulate the potential null values and pass or return it safely without worrying about the exception. Without Optional, when a method signature has return type of certain object.
One way to approach this (although still somewhat clunky) is to use a construct that's sometimes called a "Maybe" monad.
Using that, the code would become something like this (which you may or may not prefer!):
string city = nullPerson.With(x => x.address)
.With(x => x.city);
However, rejoice because C# is getting the "Safe Navigation" operator (?.
) in the next version*.
With this new ?.
operator, the code would look like this:
city = nullPerson?.address?.city;
(*Allegedly...)
After reading many questions trying to solve the same problem, I would go out on a limb and say that there is currently no way to create really elegant chained null check, where elegant would mean not adding indirection to each component of the chain.
Wrapping the chain in a lambda evaluation is perhaps the least terrible way to do it at the time, and it would only work in:
CheckNull<string>(() => nullPerson.contact.address.city);
T CheckNull<T>(Func<T> f) { try { return f(); } catch { return default(T); } }
I'd rather encourage you to try and follow the Law of Demeter that says that your object shouldn't know about the inner workings of the objects it is working with and ask them to return the value any way they want to instead of going down the class tree.
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