while (booleanExpression) {
statement; // 或語句塊 { ... }
}
執行邏輯:
關鍵點:
int i = 0;
while (i != 10) {
Console.WriteLine(i);
i++; // 關鍵:更新哨兵變量,最終使條件為 false
}
// 輸出 0 到 9
💡 `i` 稱作**哨兵變量**,控制迴圈次數。
string line;
while ((line = reader.ReadLine()) != null) {
Console.WriteLine(line);
}
// 等價於
string line;
while (true) {
line = reader.ReadLine();
if (line == null) break;
Console.WriteLine(line);
}
利用賦值表達式的值 (賦值結果為賦入的值) 簡化代碼。
場景:用戶通過 `OpenFileDialog` 選擇文件,逐行讀取顯示在多行 `TextBox` 中。
using System.IO;
private void ofd_FileOk(object sender, CancelEventArgs e) {
string fullPath = ofd.FileName;
var fileInfo = new FileInfo(fullPath);
txtFilename.Text = fileInfo.Name; // 僅文件名
txtContent.Text = ""; // 清空舊內容
// 1. 打開文本讀取器
using (TextReader reader = fileInfo.OpenText()) { // 自動關閉/釋放
// 2. 逐行讀取迴圈
string line;
while ((line = reader.ReadLine()) != null) {
txtContent.Text += line + Environment.NewLine; // 追加行 + 換行
}
// using 區塊結束自動調用 reader.Close()
}
}
| 錯誤現象 | 原因 | 修正 |
|---|---|---|
| 迴圈不結束 | 未更新條件變量 (如忘記 `i++` 或 `ReadLine()`) | 檢查迴圈體末尾是否有推進邏輯 |
| 少讀最後一行 | 先判斷後讀取,導致 EOF 行未處理 | 採用 `while ((line = reader.ReadLine()) != null)` 模式 |
| 文件被佔用無法刪除 | 未調用 `Close()`/`Dispose()` | 務必用 `using` 或 `try/finally` 關閉 |
| 中文亂碼 | 編碼不匹配 (預設 UTF-8,文件為 GB2312) | `new StreamReader(path, Encoding.GetEncoding("GB2312"))` |
| 迴圈類型 | 判斷時機 | 適用場景 |
|---|---|---|
| while | **前置**判斷 | 次數未知、可能零次執行 (如讀取流、輪詢條件) |
| do-while | **後置**判斷 | **至少執行一次** (如菜單顯示、輸入驗證) |
| for | 前置判斷 + 內置初始化/遞增 | 已知次數、計數器驅動 (如遍歷數組、索引迴圈) |
using (var reader = fileInfo.OpenText()) {
var sb = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null) {
sb.AppendLine(line);
}
txtContent.Text = sb.ToString(); // 一次性賦值
}