在 C# 開發中,遍歷集合是基礎且高頻的操作。不同集合類型(陣列、List、Dictionary、DataTable 等)雖均實作 IEnumerable,但其遍歷方式、效能特性與適用場景各有差異。本文系統整理七大常見集合的遍歷模式,並提供效能優化與避坑建議。
// 遍歷名稱
foreach (string name in Enum.GetNames(typeof(Color)))
{
Console.WriteLine(name);
}
// 遍歷值
foreach (Color val in Enum.GetValues(typeof(Color)))
{
Console.WriteLine($"Name: {val}, Value: {(int)val}");
}
提示:Enum.GetValues 回傳的是底層型別陣列,直接轉型即可;若需名稱值對,可用 Enum.GetNames 搭配 Enum.Parse。
ArrayList list = new ArrayList { "A", "B", "C" };
foreach (string item in list) { /* ... */ }
// Queue / Stack 同理,順序分別為 FIFO / LIFO
Queue q = new Queue(list);
foreach (string s in q) { /* 先進先出 */ }
Stack st = new Stack(list);
foreach (string s in st) { /* 先進後出 */ }
注意:非泛型集合元素為 object,遍歷時需確認型別一致,否則易發生 InvalidCastException。
// 遞迴遍歷所有子控制項(含巢狀容器)
void TraverseControls(Control parent)
{
foreach (Control ctl in parent.Controls)
{
if (ctl is ListBox || ctl.Name == "listBox1")
{
parent.Controls.Remove(ctl); // 移除時不可直接在 foreach 中修改集合,建議先收集再移除
}
if (ctl.HasChildren) TraverseControls(ctl);
}
}
陷阱:在 foreach 中直接呼叫 Remove 會拋出異常,正確做法是先 ToList() 或反向 for 迴圈。
var dict = new Dictionary<string, int> { { "A", 1 }, { "B", 2 } };
// 遍歷鍵值對
foreach (var kvp in dict)
{
Console.WriteLine($"{kvp.Key} = {kvp.Value}");
}
// 僅遍歷 Keys / Values
foreach (var key in dict.Keys) { /* ... */ }
foreach (var val in dict.Values) { /* ... */ }
// 高效能查找
if (dict.TryGetValue("A", out int v)) { /* ... */ }
建議:新專案優先使用泛型 Dictionary<TKey, TValue>,避免裝箱/拆箱開銷。
DataSet ds = GetDataSet();
// 遍歷 Tables
foreach (DataTable dt in ds.Tables)
{
Console.WriteLine($"Table: {dt.TableName}");
// 遍歷 Rows
foreach (DataRow row in dt.Rows)
{
Console.WriteLine(row["ID"]);
}
// 遍歷 Columns
foreach (DataColumn col in dt.Columns)
{
Console.WriteLine(col.ColumnName);
}
}
// 使用 Select 篩選後遍歷
DataRow[] filtered = dt.Select("Age > 18");
foreach (DataRow row in filtered) { /* ... */ }
效能提示:大量資料時,DataTable.AsEnumerable() 配合 LINQ 查詢比 Select 字串解析更快且型別安全。
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.IsNewRow) continue; // 跳過新增列
var id = row.Cells["ID"].Value?.ToString();
}
// 簡單字串項目
foreach (var item in listBox1.Items) { /* item 為 string */ }
// 複雜物件綁定:設定 DisplayMember / ValueMember
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Id";
comboBox1.DataSource = GetUsers(); // List
// 遍歷取得完整物件
foreach (User u in comboBox1.Items)
{
Console.WriteLine($"{u.Name} - {u.Id}");
}
| 集合類型 | 推薦遍歷方式 | 備註 |
|---|---|---|
| Array / List<T> | foreach / for | for 適合需索引或移除元素場景 |
| Dictionary<TKey,TValue> | foreach (var kvp in dict) | 避免 Keys/Values 獨立遍歷造成雜湊查找重複 |
| DataTable | AsEnumerable() + LINQ | 大量資料效能優於 Rows 集合 |
| UI 控制項集合 | 遞迴 + ToList() | 移除元素時不可直接在 foreach 中操作 |
掌握各集合的遍歷特性,能寫出更簡潔、高效且不易出錯的程式碼。