嘗試在 foreach 迴圈中移除 List<T> 元素:
string temp = name.Text;
foreach (LCourse cou in Data.myCourse)
{
if (cou.name == temp)
{
Data.myCourse.Remove(cou); // 編譯通過,運行拋出 InvalidOperationException
break;
}
}
foreach (int i in myArray) { i += 8; }
// 編譯錯誤:CS1656 迭代變數唯讀
class MyClass { private int i; public void Change() { i = 98; } }
foreach (MyClass mc in myArray) { mc.Change(); }
// 編譯通過,但運行拋出 NullReferenceException(陣列元素未初始化)
List list = new List { "ab", "cd" };
foreach (string s in list) { list.Remove(s); }
// 編譯通過,運行拋出 InvalidOperationException:集合已修改,無法繼續枚舉
| 操作 | 結果 | 原因 |
|---|---|---|
| 賦值給迭代變數 (值型別) | 編譯錯誤 | 迭代變數為 readonly 複本 |
| 呼叫迭代變數方法修改內部狀態 (參考型別) | 允許 | 修改的是「物件內容」,非變數本身 |
在迴圈中 Add/Remove 集合元素 | 運行時異常 | 枚舉器偵測集合版本號變更,拋出 InvalidOperationException |
移除後立即 break | 可行 | 枚舉器尚未嘗試 MoveNext,版本檢查未觸發 |
for (int i = list.Count-1; i >= 0; i--) if (cond) list.RemoveAt(i);var toRemove = list.Where(x => cond).ToList(); foreach (var x in toRemove) list.Remove(x);list.RemoveAll(x => cond); (單行、高效、安全)while (enumerator.MoveNext()) { if (cond) { enumerator.Remove(); } } (需 IList 實作)foreach 設計初衷是「唯讀遍歷」。理解其背後的 IEnumerator 機制(版本號檢查、Current 唯讀),能避免常見運行時異常,並選擇正確的集合操作模式。