引子: 昨天做老師的網站作業。要對一些對象做添加修改刪除處理。別的到沒什麼,刪除時出現了點問題似的。 因為是從一個類的集合中刪除掉一個元素。這樣就要遍曆整個集合,而foreach正是為遍曆準備的新玩意。自然而然用上了。於是代碼類似如下: string temp = name.Text; // 從TextBox中讀出資料 foreach (LCourse cou in Data.myCourse) // 在List<LCourse>中遍曆 { if (cou.name == temp) // 判斷cou的名字匹配 { Data.myCourse.Remove(cou); // 匹配的即為要刪除的,從列表中去除 break; // 跳出迴圈 } } 很容易就想到這麼用foreach,貌似也沒錯誤。但是印象中關於foreach的注意點就是只適用於遍曆讀取,不能修改。上邊的代碼卻刪除成功。這樣,矛盾的種子就種在了心裡,到底foreach是個什麼東西? 過程: 看了MSDN文檔,可是文檔裡的樣本用到foreach時都是遍曆讀取每個元素,所以協助不大。相關測試,異常,編譯錯誤反倒有很大用處。 過程細節和總結: 1 ,自訂整型數組然後遍曆修改 foreach(int myint in myArray) { myint+=8;} 錯誤 1 “myint”是一個“foreach 迭代變數”,無法為它賦值 G:\TEST\VS..C#\testforeach\Program.cs 15 27 testforeach 2 ,自訂類,在類中定義函數對私人成員進行操作,然後遍曆類對象並調用函數 public class MyClass // 自訂的測試類別 { private int i = 0; public void change() { i = 98; } public override string ToString() { return i.ToString(); } } MyClass[] myTest = new MyClass[10]; // 測試程式碼片段 foreach (MyClass mc in myTest) { mc.change(); Console.WriteLine(mc.ToString()); } 通過了編譯,但是拋出異常,NullRefferenceException,未將對象引用設定到對象的執行個體。 3 ,就是像開頭測試的例子,稍有改動,移除後不用break跳出 List<string> myString = new List<string>(); myString.Add("ab"); myString.Add("cd"); foreach (string s in myString) { myString.Remove(s); } 編譯通過了,但運行時拋出異常,InvalidOperationException,集合已修改;可能無法執行枚舉操作。 通過上面三個測試例子和開頭的實際例子,我貌似看到了foreach的某種東西。 第一,不能修改的是foreach引用變數,因為它是引用的,對它的修改沒有意義也沒有作用,它就像一個c/c++指標那樣對集合中的元素進行指向引用;我們能通過引用看到它,但是沒有能力動它。 第二,in之前的變數是引用變數,但in之後的集合確是實實在在的,所以可以對它操作,像.ADD();REMOVE()等方法可以使用。 第三,foreach引用變數大概是通過地址指向後面的集合(我猜想跟c/c++的指標很像),當修改了集合的元素時,地址可能發生某種改變,所以不跳出迴圈繼續遍曆時,就可能出現引用找不到的情況。 最後,也許說的不精準,但這就是我理解的全部了。首先表揚下自己這樣的思路和精神,至於技術深度,大概沒什麼。呵呵,再接再厲。 by 千冰念 @YITIAN Studio |