As stated, the reason why is that concatenating null is taken to be the same as concatenating an empty string.
It's worth considering why this behaviour is useful.
Normally, there are two sensible things we can do with an binary operator when one of the operands is null:
- The result is null.
- The operation is a no-op, and we're left with the other operand.
It makes sense for instance, that ((int?)null) + 3
results in null
, and generally either this will be the most useful result, or one we will consciously guard against (that is, we'll add code to catch the null case explicitly).
But there are two reasons to not do this with string concatenation.
The first is to consider, that since concatenation means not an arithmetic calculation, but sticking two things together, then what is the most reasonable result of sticking null onto the beginning or end of something? It's easy to make the case that this should do nothing, rather than return null.
The second is that in practice, there will be fewer cases where we want a + b + c + d
with strings to return null if any of those are null, than cases where we would not.
And from that, it makes sense to treat null as an empty string in concatenations. From that basis, that (string)null + (string)null
results in ""
is because we don't have a special case for concatenating too nulls.
That special case could be added, but then the property that x + "" == x + null
would no longer hold, which could lead to some strange cases.