An operation of the form x
op=
y
is processed by applying binary operator overload resolution (§7.2.4) as if the operation was written x
op y
. Then,
x
, the operation is evaluated as x
=
x
op y
, except that x
is evaluated only once.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.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
. 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
.
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.
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 §7.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. 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.