C# 程式設計/控制
條件、迭代、跳轉和異常處理語句控制程式的執行流程。
條件語句可以使用 if、switch 等關鍵字來決定某些事情。
迭代語句可以使用 do、while、for、foreach 和 in 等關鍵字來建立迴圈。
跳轉語句可以使用 break、continue、return 和 yield 等關鍵字來轉移程式控制。
條件語句根據條件決定是否執行程式碼。在 C# 中,if 語句和 switch 語句是兩種型別的條件語句。
與大多數 C# 一樣,if 語句的語法與 C、C++ 和 Java 中相同。因此,它以以下形式編寫
if (condition)
{
// Do something
}
else
{
// Do something else
}
if 語句評估其條件表示式以確定是否執行if-body。可選地,else 子句可以緊跟在if body 之後,提供當條件為false 時要執行的程式碼。使else-body 成為另一個if 語句建立了常見的if、else if、else if、else if、else 語句的級聯
using System;
public class IfStatementSample
{
public void IfMyNumberIs()
{
int myNumber = 5;
if ( myNumber == 4 )
Console.WriteLine("This will not be shown because myNumber is not 4.");
else if( myNumber < 0 )
{
Console.WriteLine("This will not be shown because myNumber is not negative.");
}
else if( myNumber % 2 == 0 )
Console.WriteLine("This will not be shown because myNumber is not even.");
else
{
Console.WriteLine("myNumber does not match the coded conditions, so this sentence will be shown!");
}
}
}
switch 語句類似於 C、C++ 和 Java 中的語句。
與 C 不同,每個case 語句都必須以跳轉語句結束(可以是 break 或 goto 或 return)。換句話說,C# 不支援從一個case 語句到下一個case 語句的“穿透”(從而消除了 C 程式中常見的不預期行為來源)。但是允許“堆疊”案例,如下面的示例所示。如果使用 goto,它可以引用 case 標籤或預設 case(例如 goto case 0 或 goto default)。
default 標籤是可選的。如果沒有定義預設情況,那麼預設行為是不執行任何操作。
一個簡單的例子
switch (nCPU)
{
case 0:
Console.WriteLine("You don't have a CPU! :-)");
break;
case 1:
Console.WriteLine("Single processor computer");
break;
case 2:
Console.WriteLine("Dual processor computer");
break;
// Stacked cases
case 3:
// falls through
case 4:
// falls through
case 5:
// falls through
case 6:
// falls through
case 7:
// falls through
case 8:
Console.WriteLine("A multi processor computer");
break;
default:
Console.WriteLine("A seriously parallel computer");
break;
}
與 C switch 語句相比,一個很好的改進是 switch 變數可以是字串。例如
switch (aircraftIdent)
{
case "C-FESO":
Console.WriteLine("Rans S6S Coyote");
break;
case "C-GJIS":
Console.WriteLine("Rans S12XL Airaile");
break;
default:
Console.WriteLine("Unknown aircraft");
break;
}
迭代語句建立一個迴圈程式碼,以便執行可變次數。在 C# 中,for 迴圈、do 迴圈、while 迴圈和 foreach 迴圈是迭代語句。
do...while 迴圈也與其他從 C 派生的語言具有相同的語法。它以以下形式編寫
- do...while-loop ::= "do" body "while" "(" condition ")"
- condition ::= boolean-expression
- body ::= statement-or-statement-block
do...while 迴圈總是執行其body 一次。在第一次執行之後,它會評估其condition 以確定是否再次執行其body。如果condition 為true,則執行body。如果condition 在body 執行後再次評估為true,則再次執行body。當condition 評估為false 時,do...while 迴圈結束。
using System;
public class DoWhileLoopSample
{
public void PrintValuesFromZeroToTen()
{
int number = 0;
do
{
Console.WriteLine(number++.ToString());
} while(number <= 10);
}
}
上面的程式碼將從 0 到 10 的整數寫入控制檯。
for 迴圈也與其他從 C 派生的語言具有相同的語法。它以以下形式編寫
- for-loop ::= "for" "(" initialization ";" condition ";" iteration ")" body
- initialization ::= variable-declaration | list-of-statements
- condition ::= boolean-expression
- iteration ::= list-of-statements
- body ::= statement-or-statement-block
initialization 變數宣告或語句在第一次遍歷for 迴圈時執行,通常用於宣告和初始化索引變數。在每次遍歷body 之前評估condition 表示式以確定是否執行 body。它通常用於測試索引變數是否超過某個限制。如果condition 評估為true,則執行body。在每次遍歷body 之後執行iteration 語句,通常用於增加或減少索引變數。
public class ForLoopSample
{
public void ForFirst100NaturalNumbers()
{
for (int i = 0; i < 100; i++)
{
System.Console.WriteLine(i.ToString());
}
}
}
上面的程式碼將從 0 到 99 的整數寫入控制檯。
在 C# 中,foreach 語句類似於 for 語句,它們都允許程式碼迭代集合中的專案,但 foreach 語句缺少迭代索引,因此它即使對於完全沒有索引的集合也能正常工作。它的寫法如下:
- foreach-loop ::= "foreach" "(" variable-declaration "in" enumerable-expression ")" body
- body ::= statement-or-statement-block
enumerable-expression 是一個實現了 '''IEnumerable''' 的型別的表示式,因此它可以是陣列或集合。variable-declaration 宣告一個變數,該變數將在每次遍歷body時被設定為enumerable-expression 的後續元素。當enumerable-expression 中沒有更多元素可以分配給variable-declaration 的變數時,foreach 迴圈退出。
public class ForEachSample
{
public void DoSomethingForEachItem()
{
string[] itemsToWrite = {"Alpha", "Bravo", "Charlie"};
foreach (string item in itemsToWrite)
System.Console.WriteLine(item);
}
}
在上面的程式碼中,foreach 語句迭代字串陣列的元素,將 "Alpha"、"Bravo" 和 "Charlie" 寫入控制檯。
while 迴圈的語法與其他源自 C 的語言相同。它的寫法如下:
- while-loop ::= "while" "(" condition ")" body
- condition ::= boolean-expression
- body ::= statement-or-statement-block
while 迴圈評估其condition 以確定是否執行其body。如果condition 為true,則body 執行。如果condition 隨後再次評估為true,則body 再次執行。當condition 評估為false 時,while 迴圈結束。
using System;
public class WhileLoopSample
{
public void RunForAWhile()
{
TimeSpan durationToRun = new TimeSpan(0, 0, 30);
DateTime start = DateTime.Now;
while (DateTime.Now - start < durationToRun)
{
Console.WriteLine("not finished yet");
}
Console.WriteLine("finished");
}
}
跳轉語句可用於使用諸如 break、continue、return、yield 和 throw 等關鍵字來轉移程式控制。
break 語句用於退出 switch 語句中的 case,也用於退出 for、foreach、while、do..while 迴圈,這將把控制權轉移到迴圈結束後的下一條語句。
using System;
namespace JumpSample
{
public class Entry
{
static void Main(string[] args)
{
int i;
for (i = 0; i < 10; i++) // see the comparison, i < 10
{
if (i >= 3)
{
break;
// Not run over the code, and get out of loop.
// Note: The rest of code will not be executed,
// & it leaves the loop instantly
}
}
// Here check the value of i, it will be 3, not 10.
Console.WriteLine("The value of OneExternCounter: {0}", i);
}
}
}
continue 關鍵字在迴圈結束之前轉移程式控制。然後檢查迴圈的條件,如果滿足條件,則迴圈執行另一次迭代。
using System;
namespace JumpSample
{
public class Entry
{
static void Main(string[] args)
{
int OneExternCounter = 0;
for (int i = 0; i < 10; i++)
{
if (i >= 5)
{
continue; // Not run over the code, and return to the beginning
// of the scope as if it had completed the loop
}
OneExternCounter += 1;
}
// Here check the value of OneExternCounter, it will be 5, not 10.
Console.WriteLine("The value of OneExternCounter: {0}", OneExternCounter);
}
}
}
return 關鍵字標識函式或方法的返回值(如果有),並將控制權轉移到函式的末尾。
namespace JumpSample
{
public class Entry
{
static int Fun()
{
int a = 3;
return a; // the code terminates here from this function
a = 9; // here is a block that will not be executed
}
static void Main(string[] args)
{
int OnNumber = Fun();
// the value of OnNumber is 3, not 9...
}
}
}
yield 關鍵字用於定義一個迭代器塊,該塊為列舉器生成值。它通常用在 IEnumerable 介面的方法實現中,作為建立迭代器的一種簡單方法。它的寫法如下:
- yield ::= "yield" "return" expression
- yield ::= "yield" "break"
以下示例演示了在 MyCounter 方法中使用 yield 關鍵字。此方法定義一個迭代器塊,並將返回一個列舉器物件,該物件生成從零到 stop 的計數器值,每次生成的值都增加 step。
using System;
using System.Collections;
public class YieldSample
{
public static IEnumerable MyCounter(int stop, int step)
{
int i;
for (i = 0; i < stop; i += step)
{
yield return i;
}
}
static void Main()
{
foreach (int j in MyCounter(10, 2))
{
Console.WriteLine("{0} ", j);
}
// Will display 0 2 4 6 8
}
}
throw 關鍵字丟擲異常。如果它位於 try 塊內,它將把控制權轉移到與異常匹配的 catch 塊 - 否則,它將檢查任何呼叫函式是否包含在匹配的 catch 塊內,並將執行轉移到那裡。如果沒有任何函式包含 catch 塊,則程式可能會由於未處理的異常而終止。
namespace ExceptionSample
{
public class Warrior
{
private string Name { get; set; }
public Warrior(string name)
{
if (name == "Piccolo")
{
throw new Exception("Piccolo can't battle!");
}
}
}
public class Entry
{
static void Main(string[] args)
{
try
{
Warrior a = new Warrior("Goku");
Warrior b = new Warrior("Vegeta");
Warrior c = new Warrior("Piccolo"); // exception here!
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
異常和 throw 語句在異常章節中進行了更詳細的描述。