C# 学习笔记 - 1.5 - 控制流

发布时间 2023-08-21 20:31:17作者: Snoopy1866

控制流

条件语句、迭代语句、跳转语句和异常处理语句控制程序的执行流。

  • 条件语句使用关键字 if, switch 来决定执行某些语句
  • 迭代语句使用关键字 do, while, for, foreach 和 in 创建一个循环
  • 跳转语句使用关键字 break, continue, return 和 yield 转移程序控制

条件语句(Conditional statement)

if statement

C# 中的 if 语句的语法与 C, C++ 和 Java 相同:

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

if 语句计算条件表达式决定是否执行 if 语句块(if-body),否则执行 else 语句块(else-body),else 语句块是可选的。else 语句块中可以使用层叠(common cascade)的 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 statement

C# 中的 switch 语句的语法与 C, C++ 和 Java 相似:

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;
}

其中,default 语句是可选的。如果没有定义 default 语句,则会隐式添加一个空的 default 语句。

不同于 C,C# 中的 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;
}

迭代语句(Iteration statement)

do ... while loop

do ... while 循环语法:
do body while (condition)

do ... while 循环始终会执行一次循环体,然后判断是否满足 while 中的条件,决定是否再次执行循环体。

using System;

public class DoWhileLoopSample
{
    public void PrintValuesFromZeroToTen
    {
        int number = 0;

        do
        {
            Console.WriteLine(number++.ToString());
        }
        while (number <= 10)
    }
}

for loop

for 循环语法:
for (initialization; condition; iteration) body

  • initialization : 声明和初始化索引变量(index variable
  • condition : 决定是否执行循环体的条件
  • iteration : 循环体之后执行的语句,通常用于索引变量的自增或自减
public class ForLoopSample
{
    public void ForFirst100NaturalNumbers()
    {
        for (int i = 0; i < 100; i++)
        {
            System.Console.WriteLine(i.ToString());
        }
    }
}

foreach loop

foreach 循环与 for 循环相似,不过它没有迭代索引,所以可以用于对集合元素的迭代,语法:
foreach (variable-declaration in enumerable-expression) body

  • enumerable-expression : 一种实现了 IEnumerable 的类型的表达式,因此可用于任何数组或集合中
  • variable-declaration : 一个变量,表示循环体执行过程中 enumerable-expression 的连续元素,当没有更多元素可赋值给该变量时,循环结束
public class ForEachSample
{
    public void DoSomethingForEachItem()
    {
        string[] itemsToWrite = {"Alpha", "Bravo", "Charlie"};

        foreach (string item in itemsToWrite)
        {
            System.Console.WriteLine(item);
        }
    }
}

while loop

while 循环语法:
while (condition) body

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");
    }
}

跳转语句(Jump statement)

break

break 语句用于从 switch 语句的一个分支中退出,也可用于在 for, foreach, while, do ... while 语句中退出整个循环(after the end of the loop)。

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

continue 语句用于退出当前循环(before the end of a loop)。

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

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

yield 关键字用于定义用于为枚举器生成值的迭代器块(iterator block),通常用在实现 IEnumerable 接口的方法中,来实现一个迭代器。

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

throw 关键字用于抛出异常。
如果它位于 try 语句块内,它将把控制转移到匹配这个异常的 catch 语句块,否则,它将检查当前调用环境下是否有任何包含匹配这个异常的 catch 语句块的函数(it will check if any calling functions are contained within the matching catch block),并将控制转移到那里。如果没有函数包含匹配这个异常的 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);
            }
        }
    }
}