Why is the result of adding two zero rows non-zero?

I played in C # when I came across this weird behavior in .Net programming.

I wrote 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 result as No meow , which means the string is not null . How is this possible? Why is adding two null strings a non- null string?

When debugging, when I check the xyz value after adding it to myself, its value is "" (no characters).

+42
string null c #
Feb 14 '14 at 11:39
source share
6 answers

From MSDN :

In string concatenation operations, the C # compiler treats an empty string in the same way as an empty string,

Although xyz is null, a call to the + = operator (which translates to a call to the + (*) operator), it does not throw a NullReferenceException because it is a static method. In pseudo code:

 xyz = String.+(null, null); 

The implementation then interprets this as if it were

 xyz = String.+("", ""); 



(*) Section Β§7.17.2 of the C # specification:

An operation of the form x op = y is processed by applying the overload resolution of binary operators (Β§7.3.4), as if the operation were written x op y.

+66
Feb 14 '14 at 11:41
source share

When you use the += operator, you actually call the string.Concat method, which, as stated in the documentation:

The method combines str0 and str1; it does not add delimiters. An empty string is used instead of any null argument.

Actually this code:

 string xyz = null; xyz += xyz; 

will be compiled to:

 IL_0000: ldnull IL_0001: stloc.0 // xyz IL_0002: ldloc.0 // xyz IL_0003: ldloc.0 // xyz IL_0004: call System.String.Concat IL_0009: stloc.0 // xyz 
+24
Feb 14 '14 at 11:43
source share

As indicated, the reason is that zero concatenation is considered the same as empty string concatenation.

It is worth considering why this behavior is useful.

Typically, there are two reasonable things we can do with a binary operator when one of the operands is null:

  • The result is null.
  • The operation is no-op, and we are left with another operand.

It makes sense, for example, that ((int?)null) + 3 leads to null , and usually either it will be the most useful result, or one that we will consciously protect (that is, we will add code to catch the null value of the case explicitly )

But there are two reasons not to do this when concatenating strings.

Firstly, it should be borne in mind that since concatenation does not mean arithmetic calculation, but the combination of two things together, what is the most reasonable result of sticking a zero value to the beginning or end of something? It is easy to make it do nothing and not return null.

Secondly, in practice there will be fewer cases where we want a + b + c + d with strings to return null if any of them is null than when we did not.

And from this it makes sense to consider null as an empty string in concatenations. Based on this, (string)null + (string)null leads to "" , because we have no special case for concatenating too zeros.

This special case can be added, but then the property x + "" == x + null will no longer be fulfilled, which may lead to some strange cases.

+6
Feb 14 '14 at 16:54
source share

This is because the += operator adds the Null to Empty line.

therefore, the compiler adds an empty string to the existing string object.

So these are Empty and Not null.

+2
Feb 14 '14 at 11:42
source share

try it...

 static void TestNullFunc(string abc) { if (string.IsNullOrEmpty( abc)) { Console.WriteLine("meow THERE ! "); } else { Console.WriteLine("No Meow "); } } 
+2
Feb 14 '14 at 12:05
source share

C # borrows the behavior of its + operator from Java. If any of the operands in + is a string, the + operator calls String.Concat , which takes an Object type and concatenates the results of calling ToString on each non-empty object that is passed to it. The fact that null references are simply ignored is only a small part of how String.Concat operands String.Concat not treated as "strings" as such; a much more noticeable aspect of this behavior is that types that are not strings have their own ToString method, regardless of whether they were otherwise implicitly convertible to string .

+1
Feb 14 '14 at 19:25
source share



All Articles