Conditional Default Values for Strings in C#

1 year ago · March 17, 2018 · 12:56 pm

This week I implemented a feature to show the user additional info about opened files in the app. For this purpose, a tooltip is shown as soon as the user hovers over some titlebars containing the filename. Since this feature just adds information to display on-demand, it was especially important to not make the app crash due to errors and exceptions that may occur when reading the desired fileinfo. For example, the file might not be readable at the required moment.

Therefore, I chose a defensive/pessimistic approach, in which we assume that the reading of the file info will eventually go wrong, and provide some non-empty default values to fall back to. The actual file info to display comprised its absolute path, date of last modification and its size in a human readable format (e.g. 2,4 MB). We use ☆ to refer to either of these from now on.

So, for a robust implementation in C# we test ☆ for both the null value and the empty string, and assign a default value of "Not available" in both cases.

We have multiple ways to do so.

First, the naive approach, where we start with assigning the default value, and append an if-statement to assign the new value if its not null or empty.

string val = "Not available"; 
if ( !string.IsNullOrEmpty(☆) )
{
    val = ☆;
}

We can achieve the same with a one-liner. To do so, we use either the if-shorthand

or the null-coalescing operator:

string val = ☆ ?? "Not available";

However, in the latter case, we would not assign the default value in case ☆ is equal to the empty string, since the ?? operator only checks for the null value. One approach to deal with this is to wrap the value to be tested in some function, which returns null if the string is empty. So now we have:

string val = NullIfEmpty(☆) ?? "Not available";

Okay let's summarize. The naive approach is somewhat readable and optimal, but spreads over multiple lines. At this point I'd like to point out that, for me personally, having the head and body of an if-statement is no option for me, since it drastically makes debugging harder. Also it contains a negation which adds a small hurdle to the reader to understand. We can do better than that.

The if-shorthand version is optimal, only consumes a single line, but requires the reader to know the if-shorthand's semantics.

Finally, the version where we use the null-coalescing operator is the shortest one (excluding the definition of the NullIfEmpty method), but is the least readable as the reader is required to understand the semantics of the ?? operator to get why the call to NullIfEmpty is necesarry in the first place.

In the context of my C# implementation, I ended up with the if-shorthand version due to its compactness and readability.