Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About implicitly convert type 'int' to 'char', why it is different between `s[i] += s[j]` and `s[i] = s[i]+s[j] `

Tags:

c#

The sample code for demo:

public void ReverseString(char[] s) {
  for(int i = 0, j = s.Length-1; i < j; i++, j--){
        //s[i] = s[i]+s[j]; //<-- error           
        s[i] += s[j];       //<-- ok 

        s[j] = (char)(s[i] - s[j]); //<-- cast
        s[i] -= s[j];
    }
}

As the above code snippet, while s[i] += s[j] is fine without any error. Its equivalent statement s[i] = s[i]+s[j] will cause error as follows

error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?

My question is what's their difference and why. Thanks in advance.

like image 492
Eric Tsui Avatar asked Apr 01 '19 10:04

Eric Tsui


1 Answers

Its equivalent statement s[i] = s[i]+s[j] will cause error as follows

It's not an equivalent statement, although I can understand why you'd expect it to be. From section 12.18.3 of the C# 5 ECMA standard, around compound assignment:

An operation of the form x op= y is processed by applying binary operator overload resolution (§12.4.5) as if the operation was written x op y. Then,

  • If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
  • Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.

That second bullet is what's happening here. There's no operator to add char values together - what there is is an int +(int, int) operator, which is what's selected - and there's an explicit conversion from int to char.

So this:

s[i] += s[j];

is more equivalent to

s[i] = (char) (s[i] + s[j]);

... which compiles fine.

like image 150
Jon Skeet Avatar answered Nov 01 '22 18:11

Jon Skeet