Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant way to do Chained Null Checks

Tags:

c#

lambda

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.

like image 549
Pankaj Avatar asked Apr 10 '14 11:04

Pankaj


People also ask

Where do you put null checks?

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.

How to handle null checks in Java 8?

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.

How do I avoid multiple nulls in Java 8?

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.


2 Answers

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...)

like image 165
Matthew Watson Avatar answered Oct 29 '22 17:10

Matthew Watson


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.

like image 26
samy Avatar answered Oct 29 '22 18:10

samy