Using null-coalescing to find item in multiple collections

A co-worker showed me this:

var result = collection1.GetObjectByAtSpecialLocation(location) ??
collection1.GetObjectByAtLocation(parent, location) ??
collection2.GetObjectByAtSpecialLocation(location) ??
collection2.GetObjectByAtLocation(parent, location);

I’m still trying to decide whether it’s a good practice and if it’s readable or not…

In case you’re not familiar with ?? operator a.k.a null-coalescing operator it’s basically returns a default value if the left side is null so the following line means return empty string if name is null:

string result = name ?? string.Empty;

And so the code at the beginning of the post can also be written as:

var result = collection1.GetObjectByAtSpecialLocation(location);
if(result == null)
{
result = collection1.GetObjectByAtLocation(parent, location);
}

if(result == null)
{
result = collection2.GetObjectByAtSpecialLocation(location);
}

if(result == null)
{
result = collection2.GetObjectByAtLocation(parent, location);
}

Although most developers would agree that it’s easy enough to understand it’s far from being a good piece of code.

I also think that the reason that there was a need to check if an item exist over two different collections in two different ways indicates a design flow – but since we’re not living in a perfect world right now it’s impossible to merge those two collections and regardless of effort there was a good reason that they are different in the first place so I’m have to find an item in four different ways.

At first when I saw the code I cried abuse – it seemed to me that there bound to be a better way to do so without nesting four calls but after a while this solution seemed almost elegant.

What do you think?

2 thoughts on “Using null-coalescing to find item in multiple collections

  1. Definitely useful. I use this all the time. A more concise example would use LINQ's FirstOrDefault(), e.g.:

    return
      collection1.FirstOrDefault(someCondition) ??
      collection1.FirstOrDefault(someOtherCondition) ??
      collection2.FirstOrDefault(yetAnotherCondition) ??
      someDefaultFallbackValue;

    I don't like your alternative anyway; I think that assigning a local “result” variable multiple times is a smell that usually indicates you need to extract a method, which would make all those assignments into return statements (much preferred, less to keep in your mental stack) and also be slightly more efficient (although that should not be the argument here).

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.