それは他の回答によって暗示されています.C ++からの提案を支持して、これを「悪いこと」として扱いますが、「簡単な」修正は次のとおりです。
int x = 0;
x = Increment(ref x) + x;
C# では式の左から右への評価が保証されるため*、これは期待どおりの動作をします。
* C# 仕様のセクション「7.3 Operators」を引用:
式のオペランドは左から右に評価されます。たとえば、 では、の古い値を使用してF(i) + G(i++) * H(i)
メソッドが呼び出され、次にの古い値でメソッドが呼び出され、最後にの新しい値でメソッドが呼び出されます。これは、演算子の優先順位とは別のものであり、無関係です。F
i
G
i
H
i
最後の文はこれを意味することに注意してください。
int i=0, j=0;
Console.WriteLine(++j * (++j + ++j) != (++i + ++i) * ++i);
i = 0; j = 0;
Console.WriteLine($"{++j * (++j + ++j)} != {(++i + ++i) * ++i}");
i = 0; j = 0;
Console.WriteLine($"{++j} * ({++j} + {++j}) != ({++i} + {++i}) * {++i}");
これを出力します:
真
5 != 9
1 * (2 + 3) != (1 + 2) * 3
その最後の行は、前の 2 つの式で使用されたのと同じ値であると「信頼」できます。IE、加算は乗算の前に実行されますが、角かっこのため、オペランドはすでに評価されています。
これを次のように「リファクタリング」することに注意してください。
i = 0; j = 0;
Console.WriteLine(++j * TwoIncSum(ref j) != TwoIncSum(ref i) * ++i);
i = 0; j = 0;
Console.WriteLine($"{++j * TwoIncSum(ref j)} != { TwoIncSum(ref i) * ++i}");
i = 0; j = 0;
Console.WriteLine($"{++j} * {TwoIncSum(ref j)} != {TwoIncSum(ref i)} * {++i}");
private int TwoIncSum(ref int parameter)
{
return ++parameter + ++parameter;
}
まったく同じように動作します:
真
5 != 9
1 * 5 != 3 * 3
しかし、私はまだそれに依存したくない:-)