<?xml version="1.0"?>
<clause number="14.13.2" title="Compound assignment">
  <paragraph>An operation of the form x op= y is processed by applying binary operator overload resolution (<hyperlink>14.2.4</hyperlink>) as if the operation was written x op y. Then, <list><list_item> 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. </list_item><list_item> 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, 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. </list_item><list_item> Otherwise, the compound assignment is invalid, and a compile-time error occurs. </list_item></list></paragraph>
  <paragraph>The term &quot;evaluated only once&quot; means that in the evaluation of x op y, the results of any constituent expressions of x are temporarily saved and then reused when performing the assignment to x. <example>[Example: For example, in the assignment A()[B()] += C(), where A is a method returning int[], and B and C are methods returning <keyword>int</keyword>, the methods are invoked only once, in the order A, B, C. end example]</example> </paragraph>
  <paragraph>When the left operand of a compound assignment is a property access or indexer access, the property or indexer must have both a get accessor and a set accessor. If this is not the case, a compile-time error occurs. </paragraph>
  <paragraph>The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. The rule exists such that the predefined operators can be used as compound operators when the left operand is of type <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, or <keyword>char</keyword>. Even when both arguments are of one of those types, the predefined operators produce a result of type <keyword>int</keyword>, as described in <hyperlink>14.2.6.2</hyperlink>. Thus, without a cast it would not be possible to assign the result to the left operand. </paragraph>
  <paragraph>The intuitive effect of the rule for predefined operators is simply that x op= y is permitted if both of x op y and x = y are permitted. <example>[Example: In the example <code_example><![CDATA[
byte b = 0;  
char ch = '\0';  
int i = 0;  
b += 1;        // Ok  
b += 1000;      // Error, b = 1000 not permitted  
b += i;        // Error, b = i not permitted  
b += (byte)i;    // Ok  
ch += 1;       // Error, ch = 1 not permitted  
ch += (char)1;   // Ok  
]]></code_example>the intuitive reason for each error is that a corresponding simple assignment would also have been an error. end example]</example> </paragraph>
</clause>
