An operation of the form x op= y is processed by applying binary operator
overload resolution (?4.2.4) 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, 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.
?Otherwise, the compound assignment is invalid, and a compile-time error
occurs.
The term ?evaluated only once? 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: For
example, in the assignment A()[B()] += C(), where A is a method returning
int[], and B and C are
methods returning int, the methods are invoked only once, in the order A,
B, C. end example]
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.
Chapter 14 Expressions
175
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
sbyte, byte, short, ushort, or char. Even when both arguments are of one of
those types, the
predefined operators produce a result of type int, as described in ?4.2.6.2.
Thus, without a cast it would
not be possible to assign the result to the left operand.
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: In the example
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
the intuitive reason for each error is that a corresponding simple
assignment would also have been an error.
end example]