跳轉到內容

C# 程式設計/控制

來自華夏公益教科書,開放的書籍,開放的世界

條件、迭代、跳轉和異常處理語句控制程式的執行流程。

條件語句可以使用 ifswitch 等關鍵字來決定某些事情。

迭代語句可以使用 dowhileforforeachin 等關鍵字來建立迴圈。

跳轉語句可以使用 breakcontinuereturnyield 等關鍵字來轉移程式控制。

條件語句

[編輯 | 編輯原始碼]

條件語句根據條件決定是否執行程式碼。在 C# 中,if 語句和 switch 語句是兩種型別的條件語句。

if 語句

[編輯 | 編輯原始碼]

與大多數 C# 一樣,if 語句的語法與 C、C++ 和 Java 中相同。因此,它以以下形式編寫

if (condition)
{
  // Do something
} 
else
{
  // Do something else
}

if 語句評估其條件表示式以確定是否執行if-body。可選地,else 子句可以緊跟在if body 之後,提供當條件false 時要執行的程式碼。使else-body 成為另一個if 語句建立了常見的ifelse ifelse ifelse ifelse 語句的級聯

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 語句

[編輯 | 編輯原始碼]

switch 語句類似於 C、C++ 和 Java 中的語句。

與 C 不同,每個case 語句都必須以跳轉語句結束(可以是 breakgotoreturn)。換句話說,C# 不支援從一個case 語句到下一個case 語句的“穿透”(從而消除了 C 程式中常見的不預期行為來源)。但是允許“堆疊”案例,如下面的示例所示。如果使用 goto,它可以引用 case 標籤或預設 case(例如 goto case 0goto 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 迴圈

[編輯 | 編輯原始碼]

do...while 迴圈也與其他從 C 派生的語言具有相同的語法。它以以下形式編寫

do...while-loop ::= "do" body "while" "(" condition ")"
condition ::= boolean-expression
body ::= statement-or-statement-block

do...while 迴圈總是執行其body 一次。在第一次執行之後,它會評估其condition 以確定是否再次執行其body。如果conditiontrue,則執行body。如果conditionbody 執行後再次評估為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 迴圈

[編輯 | 編輯原始碼]

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 的整數寫入控制檯。

foreach 迴圈

[編輯 | 編輯原始碼]

在 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 迴圈

[編輯 | 編輯原始碼]

while 迴圈的語法與其他源自 C 的語言相同。它的寫法如下:

while-loop ::= "while" "(" condition ")" body
condition ::= boolean-expression
body ::= statement-or-statement-block

while 迴圈評估其condition 以確定是否執行其body。如果conditiontrue,則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");
    }
}

跳轉語句

[編輯 | 編輯原始碼]

跳轉語句可用於使用諸如 breakcontinuereturnyieldthrow 等關鍵字來轉移程式控制。

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 語句在異常章節中進行了更詳細的描述。

華夏公益教科書