一個看似無害的重載調用,卻因 out 參數的引用傳遞特性導致嚴重邏輯錯誤。記錄一次真實踩坑經歷,警示開發者注意值類型的引用語義。
int GetRest(out int all, out int usedCount, out int invalidCount)
{
all = 10; // 模擬 GetAll()
usedCount = 5; // 模擬 GetUsedCount()
invalidCount = 3; // 模擬 GetInvalidCount()
return all - usedCount - invalidCount; // 返回剩余量
}
調用方常不需要三個輸出值,於是寫了無參重載:
int GetRest()
{
int temp;
return GetRest(out temp, out temp, out temp); // 編譯通過!
}
out 參數本質是引用傳遞。三個形參 all、usedCount、invalidCount 綁定到同一個 temp 變量。方法內依次賦值:
all = 10 → temp = 10usedCount = 5 → temp = 5(覆蓋)invalidCount = 3 → temp = 3(再次覆蓋)最終三個輸出參數均為 3,返回值 3 - 3 - 3 = -3,完全錯誤。
int GetRest()
{
int temp1, temp2, temp3;
return GetRest(out temp1, out temp2, out temp3);
}
out/ref 參數傳遞的是變量地址,而非值副本。out/ref 才能實現多個變量別名指向同一內存,這在無意中極易發生。調試時善用「局部變量」窗口觀察地址/值變化,可快速定位此類問題。