条件语句可以根据条件是否满足或根据表达式的值来控制代码的执行分支。C#有两个控制代码的分支的结构:if语句,测试特定条件是否满足;switch语句,比较表达式和多个不同的值。
一、if语句
对于条件分支,C#继承了C和C++的if...else结构。对于用过程语言编程的人,其语法非常直观:if(condition)statement(s)elsestatement(s)如果在条件中要执行多个语句,就需要用花括号({...})把这些语句组合为一个块(这也适用于其他可以把语句组合为一个块的C#结构,如for和while循环)。bool isZero;
if (i == 0)
{
isZero = true;
WriteLine(" i 为零值");
}
Else
{
isZero = false;
WriteLine(" i为非零值");
}
还可以单独使用if语句,不加最后的else语句。也可以合并else if子句,测试多个条件。
Using System. Console;
namespace Rbsoft
{
class Program
{
static void Main()
{
WriteLine(" Type in a string");
string input;
input = ReadLine();
if (input == "")
{
WriteLine(" 您输入了一个空字符串!");
}
else if (input. Length < 5)
{
WriteLine(" 字符串少于5个字符。");
}
else if (input. Length < 10)
{
WriteLine("字符串至少有5 个但少于10 个字符。");
}
WriteLine(" The string was " + input);
}
}
添加到if子句中的else if语句的个数不受限制。注意,在上面的例子中,声明了一个字符串字符串变量input,让用户在命令行输入文本,把文本填充到input中,然后测试该字符串变量的长度。代码还显示了在C#中如何进行字符串处理。例如,要确定input的长度,可以使用input.Length。对于if,要注意的一点是如果条件分支中只有一条语句,就无须使用花括号:
if (i == 0)
WriteLine(" i 为零");
// 这样仅执行 if( i == 0 )
WriteLine(" i can be anything"); // 无论i的值是什么都将执行
但是,为了保持一致,许多程序员只要使用使用if语句,就加上花括号。
注意:在if语句中不使用花括号,可能在维护代码时导致错误。无论if语句返回true还是false,都常常给if语句添加第二个语句。每次都使用花括号,就可以避免这个编码错误。使用if语句的一个指导原则是只有语句和if语句写在同一行上,才不允许程序员使用花括号。遵守这条指导原则,程序员就不太可能在添加第二个语句时不添加花括号。
前面介绍的if语句还演示了用于比较数值的一些C#运算符。特别注意,C#使用“==”对变量进行等于比较。此时不要使用“=”,一个“=”用于赋值。
在C#中,if子句中的表达式必须等于布尔值(Boolean)。不能直接测试整数(如从函数中返回的值),而必须明确地把返回的整数转换为布尔值true或false,例如,将值与0或null进行比较:
if (DoSomething() ! = 0)
{
// 返回非零值
}
else
{
// 返回零值
}
二. switch语句
switch… case语句适合于从一组互斥的可执行分支中选择一个执行分支。其形式是switch参数的后面跟一组case子句。如果switch参数中表达式的值等于某个case子句旁边的某个值,就执行该case子句中的代码。此时不需要使用花括号把语句组合到块中;只需要使用break语句标记每段case代码的结尾即可。也可以在switch语句中包含一条default子句,如果表达式不等于任何case子句的值,就执行default子句的代码。下面的switch语句测试integerA变量的值:
switch (integerA)
{
case 1:
WriteLine(" integerA = 1");
break;
case 2:
WriteLine(" integerA = 2");
break;
case 3:
WriteLine(" integerA = 3");
break;
default:
WriteLine(" integerA is not 1, 2, or 3");
break;
}
注意:case值必须是常量表达式;不允许使用变量。
C和C++程序员应很熟悉switch…case语句,而C#的switch…case语句更安全。特别是它禁止几乎所有case中的失败条件。如果激活了块中靠前的一条case子句,后面的case子句就不会被激活,除非使用goto语句特别标记也要激活后面的case子句。编译器会把没有break语句的case子句标记为错误,从而强制实现这一约束:
Control cannot fall through from one case label ('case 2:') to another
在有限的几种情况下,这种失败是允许的,但在大多数情况下,我们不希望出现这种失败,而且这会导致出现很难察觉的逻辑错误。让代码正常工作,而不是出现异常,这样不是更好吗? 但在使用goto语句时,会在switch…cases中重复出现失败。如果确实想这么做,就应重新考虑设计方案了。下面的代码说明了如何使用goto模拟失败,得到的代码会非常混乱:
// 假定国家和语言是字符串类型
switch( country)
{ case "America":
CallAmericanOnlyMethod();
goto case "Britain";
case "France":
language = "French";
break;
case "Britain":
language = "English";
break;
}
但有一种例外情况。如果一条case子句为空,就可以从这条case子句跳到下一条case子句,这样就可以用相同的方式处理两条或多条case子句了(不需要goto语句)。
switch( country)
{
case "au":
case "uk":
case "us":
language = "English";
break;
case "at":
case "de":
language = "German";
break;
}
在C#中,switch语句的一个有趣的地方是case子句的顺序是无关紧要的,甚至可以把default子句放在最前面!因此,任何两条case都不能相同。这包括值相同的不同常量,所以不能这样编写:
// 假定国家是一个字符串类型
const string england = "uk";
const string britain = "uk";
switch( country)
{
case england:
case britain: // 这会引起编译错误!
language = "English";
break;
}
上面的代码还说明了C#中的switch语句与C++中的switch语句的另一个不同之处:在C#中,可以把字符串用作测试的变量。