Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is string.Join(string, object[]) special?

Tags:

string

.net

I was looking at the following expressions:

string.Join(",", new object[] { null, "StackOverflow" })
string.Join(",", new string[] { null, "StackOverflow" })
string.Join(",", new object[] { string.Empty, "StackOverflow" })
string.Join(",", new string[] { string.Empty, "StackOverflow" })

I would have thought they would return the same value:

,StackOverflow

However, the first expression actually returns string.Empty. This is actually defined behavior:

If the first element of values is null, the Join(String, Object[]) method does not concatenate the elements in values but instead returns String.Empty. A number of workarounds for this issue are available. The easiest is to assign a value of String.Empty to the first element of the array, as the following example shows.

Does anyone know the reason behind this inconsistency?

like image 747
Anthony Avatar asked Nov 26 '13 21:11

Anthony


1 Answers

In your favorite decompiler you can see that the code for the method is

public static string Join(string separator, params object[] values)
{
  if (values == null)
    throw new ArgumentNullException("values");
  if (values.Length == 0 || values[0] == null)
    return string.Empty;
  if (separator == null)
    separator = string.Empty;
  StringBuilder sb = StringBuilderCache.Acquire(16);
  string str1 = values[0].ToString();
  if (str1 != null)
    sb.Append(str1);
  for (int index = 1; index < values.Length; ++index)
  {
    sb.Append(separator);
    if (values[index] != null)
    {
      string str2 = values[index].ToString();
      if (str2 != null)
        sb.Append(str2);
    }
  }
  return StringBuilderCache.GetStringAndRelease(sb);
}

The part responsible for the special behavior is

  if (values.Length == 0 || values[0] == null)
    return string.Empty;

but we can see a few lines below

  string str1 = values[0].ToString();
  if (str1 != null)
    sb.Append(str1);

It seems quite strange to me to return on values[0] == null but to handle values[0].ToString() == null. Combined with the wording on MSDN ("issue", "workaround"), the fact that this overload is relatively new (.NET 4.0) and the fact the the other Joins have a different implementation that accept null as the first element, it looks like a bug to me and not really an intended exception.

Of course, this is only my interpretation and not a definitive answer...

like image 196
dee-see Avatar answered Nov 15 '22 03:11

dee-see