William Duffy

Glasgow Based C# ASP.NET Web Developer

Coalesce: ASP.NET Strings

In programming it is a common occurrence to have a list of possiblities from which you would like the first available option selected. SQL Server has a handy method (Coalesce) which makes performing this easy, but unless you are using nullable types .NET does not have a suitable alternative. Here, I will make a helper method to mimic this functionality when testing strings.

Take this example.

You have a product which can have zero to three images associated with it. There is not a one-to-many relationship with this product so the object model has three simple properties which can either store an image or be empty (image name not binary stream).
ImageOne
ImageTwo
ImageThree

Now, imagine you need to display a preview of this product before viewing it’s full details page (i.e. in an e-commerce shop). You will no doubt want to show a thumbnail version of at least one of the images next to the product, but you don’t know which property…if any, has an image associated with it. The quick route is to simply drop in a logical if block.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (string.IsNullOrEmpty(product.ImageOne) && string.IsNullOrEmpty(product.ImageTwo) && string.IsNullOrEmpty(product.ImageThree)
{
	imgImage.ImageUrl = "noimage.jpg";
}
else
{
	if (!string.IsNullOrEmpty(product.ImageOne))
	{
		imgImage.ImageUrl = product.ImageOne;
	}
	else if (!string.IsNullOrEmpty(product.ImageTwo))
	{
		imgImage.ImageUrl = product.ImageTwo;
	}
	else if (!string.IsNullOrEmpty(product.ImageThree))
	{
		imgImage.ImageUrl = product.ImageThree;
	}
}

Refactoring this logic into a reusable helper method offers a few distinct advantages and is the foundation of my Coalesce mimicking helper method.

  1. Reusable code
  2. Less possibilities for error
  3. A single point of failure

So how would we go about refactoring the above code? First, we can assume that there must be some sort of fallback value, incase all of the values passed are empty. Second, we know that the helper method has to be flexible enough to take an unlimited amount of values to assess. Finally, the method must be accessible from anywhere in our application with quick, easy, unrestricted access.

The joy of this method is that it is so simple to write, yet so effective in it’s role. Below is the new helper method in full.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
///<summary>
///Returns the first <see cref="System.String" /> in a passed paramarray which is not null or empty 
///</summary>
///<param name="fallback">The value to return if every <see cref="System.String" /> in the paramarray is null or empty</param>
///<param name="args">The paramarray of <see cref="System.String" /> to be searched</param>
///<returns>The first string that is not null or empty in the paramarray</returns>
///<remarks></remarks>
public static string GetFirstString(string fallback, params string[] strings)
{
	foreach (string s in strings)
		if (!string.IsNullOrEmpty(s))
			return s;
 
	return fallback;
}

We can now rewrite the first logical if block as follows.

1
imgImage.ImageUrl = StringTools.GetFirstString("noimage.jpg", product.ImageOne, product.ImageTwo, product.ImageThree);

This provides a very neat solution to mimicking Coalesce and the reuse value alone instantly makes up for the time required to implement it.

Happy Coding!


Categorized as Uncategorized

5 Comments

  1. Stop it. Your not allowed to get better than the rest of us!

  2. I’m just trying to fill your shoes Colin :)

  3. You could also use the C# format like …

    a = b ?? c ?? d ?? e ?? …..

    which behaves like a SQL Server Coalesce() function.

  4. Nice Eric, I’m sure that will come in very handy!

  5. George Chakhidze says:

    LINQ edition:

    public static T Coalesce(params T[] args) where T : class
    {
    return args != null ? args.FirstOrDefault(item => item != null) : null;
    }
    public static Nullable Coalesce(params Nullable[] args) where T : struct
    {
    return args != null ? args.FirstOrDefault(item => item.HasValue) : null;
    }

    As extension methods:

    public static T Coalesce(this IEnumerable items) where T : class
    {
    return items != null ? items.FirstOrDefault(item => item != null) : null;
    }
    public static Nullable Coalesce(this IEnumerable items) where T : struct
    {
    return items != null ? items.FirstOrDefault(item => item.HasValue) : null;
    }

comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

Trackbacks & Pingbacks

  1. Colin Wiseman

    Stop it. Your not allowed to get better than the rest of us!

  2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

    Trackbacks & Pingbacks

    1. William

      I’m just trying to fill your shoes Colin :)

    2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

      Trackbacks & Pingbacks

      1. Eric

        You could also use the C# format like …

        a = b ?? c ?? d ?? e ?? …..

        which behaves like a SQL Server Coalesce() function.

      2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

        Trackbacks & Pingbacks

        1. William

          Nice Eric, I’m sure that will come in very handy!

        2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

          Trackbacks & Pingbacks

          1. George Chakhidze

            LINQ edition:

            public static T Coalesce(params T[] args) where T : class
            {
            return args != null ? args.FirstOrDefault(item => item != null) : null;
            }
            public static Nullable Coalesce(params Nullable[] args) where T : struct
            {
            return args != null ? args.FirstOrDefault(item => item.HasValue) : null;
            }

            As extension methods:

            public static T Coalesce(this IEnumerable items) where T : class
            {
            return items != null ? items.FirstOrDefault(item => item != null) : null;
            }
            public static Nullable Coalesce(this IEnumerable items) where T : struct
            {
            return items != null ? items.FirstOrDefault(item => item.HasValue) : null;
            }

          Leave a Reply