This question already has an answer here:
I was fiddling around in C# when I came across this weird behavior in .Net programming.
I have written this code:
static void Main(string[] args)
{
string xyz = null;
xyz += xyz;
TestNullFunc(xyz);
Console.WriteLine(xyz);
Console.Read();
}
static void TestNullFunc(string abc)
{
if (abc == null)
{
Console.WriteLine("meow THERE ! ");
}
else
{
Console.WriteLine("No Meow ");
}
}
I got the output as No meow
, which means the string is not null
. How is this possible? Why does adding two null
strings, result in a non-null
string?
On debugging when I check the value of xyz
after adding it to itself, its value is ""
(no characters).
From MSDN:
Even though
xyz
is null, calling the += operator (which is converted to a call to the + operator (*)) on it does not throw aNullReferenceException
because it's a static method. In pseudo code:The implementation will then interpret this as if it was
(*) Section §7.17.2 of the C# specification:
Thats because the Operator
+=
adds the Null to Empty string.so, the Compiler does Adding Empty String to the Existing string Object.
So it is Empty and Not null.
When you use the
+=
operator, you are actually calling the string.Concat method, that, as stated in the documentation:In fact this code:
will be compiled in:
try this...
C# borrows the behavior of its
+
operator from Java. If either operand to+
is a string, the+
operator will callString.Concat
, which accepts typeObject
and concatenates the results of callingToString
on every non-null object that's passed to it. The fact that null references are simply ignored is only a small part of the way in which the operands toString.Concat
aren't regarded as "strings" per se; a much more noticeable aspect of this behavior is that types which aren't strings have theirToString
method called, whether or not they would otherwise be implicitly convertible tostring
.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:
It makes sense for instance, that
((int?)null) + 3
results innull
, 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.