| 運算子 | 運作順序 | 運算式值 | 副作用時間 |
|---|---|---|---|
++i / --i | 先遞增/遞減,後取值 | 新值 | 立即 |
i++ / i-- | 先取值,後遞增/遞減 | 舊值 | 序列點後 (陳述式結束前) |
int a = 5;
int b = ++a; // a=6, b=6 (前綴)
int c = 5;
int d = c++; // c=6, d=5 (後綴)
// 複雜運算式中的副作用順序
int x = 1;
int y = x++ + ++x; // C# 左到右評估:
// 1. x++ 取值 1,x 變 2
// 2. ++x 先遞增 x 變 3,取值 3
// y = 1 + 3 = 4, x = 3
// 迴圈中常見模式
for (int i = 0; i < 10; i++) { } // 後綴 (慣例)
for (int i = 0; i < 10; ++i) { } // 前綴 (效能相同,整數無差異)
// 避免:同一變數多次副作用 (未定義行為在 C/C++,C# 有定義但難讀)
int z = 1;
int result = z++ + z++ + ++z; // 請勿這樣寫
// ++i (前綴)
ldloc.0 // 載入 i
ldc.i4.1 // 載入 1
add // 相加
stloc.0 // 存回 i
ldloc.0 // 載入新值作為運算式結果
// i++ (後綴)
ldloc.0 // 載入 i
dup // 複製舊值
ldc.i4.1
add
stloc.0 // 存回 i (新值)
// 堆疊頂端仍為舊值 (dup 保留)
public static T operator ++(T t) / operator --operator +、operator - 保持一致性| 陷阱 | 說明 | 建議 |
|---|---|---|
| 運算式中混用前/後綴 | 難以推導結果 | 拆分為多行陳述式 |
| 迴圈條件中使用後綴 | while (i++ < 10) 易誤解 | 改用 while (i < 10) { ... i++; } |
| 屬性存取器副作用 | obj.Prop++ 隱含 get/set 兩次呼叫 | 避免對屬性直接遞增,改用區域變數 |
| 事件處理器註冊/移除 | event += Handler 非遞增運算子 | 切勿混淆 |
現代 JIT 編譯器對區域變數前綴/後綴產生相同機器碼。差異僅在運算式值用途。對屬性/索引器/欄位,前綴可能少一次載入,但微乎其微。可讀性優先。


