跳转到内容

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 语句在异常章节中进行了更详细的描述。

华夏公益教科书