Coder Perfect

?? Is it possible to coalesce for an empty string?

Problem

Checking a string for empty (as in “” or null) and a conditional operator is something I find myself doing more and more.

A current example:

s.SiteNumber.IsNullOrEmpty() ? "No Number" : s.SiteNumber;

This is nothing more than an extension method, and it’s the same as:

string.IsNullOrEmpty(s.SiteNumber) ? "No Number" : s.SiteNumber;

?? won’t work because it’s empty and not null. A strand of yarn. A version of?? with the IsNullOrEmpty() method would be ideal. I’m sure there’s a better method to accomplish it (hopefully! ), but I’m having trouble finding it.

Is there a better method to accomplish this, even if it’s only in.Net 4.0?

Asked by Nick Craver

Solution #1

With?? in C#, we can already swap values for null. All we need is an extension that turns an empty string to null, which we can then use as follows:

s.SiteNumber.NullIfEmpty() ?? "No Number";

Extension class:

public static class StringExtensions
{
    public static string NullIfEmpty(this string s)
    {
        return string.IsNullOrEmpty(s) ? null : s;
    }
    public static string NullIfWhiteSpace(this string s)
    {
        return string.IsNullOrWhiteSpace(s) ? null : s;
    }
}

Answered by D’Arcy Rittich

Solution #2

There is no built-in technique to accomplish this. However, you could make your extension method return a string or null, allowing the coalescing operator to function. However, this would be strange, and I like your existing approach.

Why not create an extension method that returns the value or a default, since you’re currently using one:

string result = s.SiteNumber.ConvertNullOrEmptyTo("No Number");

Answered by Reed Copsey

Solution #3

I realize this is an old question, but I needed an answer, and none of the options above met my needs as well as what I came up with:

private static string Coalesce(params string[] strings)
{
    return strings.FirstOrDefault(s => !string.IsNullOrEmpty(s));
}

Usage:

string result = Coalesce(s.SiteNumber, s.AltSiteNumber, "No Number");

EDIT: This function could be written even more succinctly as:

static string Coalesce(params string[] strings) => strings.FirstOrDefault(s => !string.IsNullOrEmpty(s));

Answered by sfsr

Solution #4

I have a few utility extensions that I enjoy using:

public static string OrDefault(this string str, string @default = default(string))
{
    return string.IsNullOrEmpty(str) ? @default : str;
}

public static object OrDefault(this string str, object @default)
{
    return string.IsNullOrEmpty(str) ? @default : str;
}

Edit: As a result of sfsr’s response, I’m going to start include this variant in my toolbox:

public static string Coalesce(this string str, params string[] strings)
{
    return (new[] {str})
        .Concat(strings)
        .FirstOrDefault(s => !string.IsNullOrEmpty(s));
}

Answered by Justin Morgan

Solution #5

I simply utilize the NullIfEmpty extension method, which returns null if the string is empty, allowing the?? (Null Coalescing Operator) to function normally.

public static string NullIfEmpty(this string s)
{
    return string.IsNullOrEmpty(s) ? null : s;
}

This allows?? to be used normally, making chaining much easier to read.

string string1 = string2.NullIfEmpty() ?? string3.NullIfEmpty() ?? string4;

Answered by jjr2000

Post is based on https://stackoverflow.com/questions/2420125/coalesce-for-empty-string