09. 语句

9.1 什么是语句

C#中的语句非常类似于C和C++的语句。

  • 语句是描述一个类型或告诉程序去执行一个动作的源代码指令。
  • 有三种主要语句种类
    • 声明语句:声明类型或变量的语句。
    • 嵌入语句:执行动作或管理控制流的语句。
    • 标签语句:控制可以跳转到的语句。
简单语句由一个表达式和后面跟着的分号组成。
块是匹配的大括号括起来的语句序列。

说明:块在语法上算作一个单条嵌入语句。任何语法上需要一个嵌入语句的地方,都可以使用块。

空语句仅有一个分号组成。可以把空语句用在任何语言的语法需要一条嵌入语句而程序逻辑又不需要任何动作的地方。


9.2 表达式语句

表达式返回值,但它们也有副作用(side effect)。

  • 副作用是一种影响程序状态的行为。
  • 许多表达式被求值只是为了它们的副作用。
可以在表达式后面旋转语句终结符(分号)从一个表达式创建一条语句。表达式返回的任何值都被丢弃。


9.3 控制流语句

C#提供与现代编程语言共同的控制流结构。

  • 条件执行依据一个条件执行或跳过一个代码片段。条件执行语句如下:
    • if
    • if...else
    • switch
  • 循环语句重复执行一个代码片段。循环语名在如下:
    • while
    • do
    • for
    • foreach
  • 跳转语句把控制流从一个代码片段改变到另一个代码片段中的指定语句。跳转语句如下:
    • break
    • continue
    • return
    • goto
    • throw

9.4 if语句

if (条件)

{

代码块

}


9.5 if..else语句

if(条件)

{  //条件为真执行代码块

 } 

else

{  //条件为假执行代码块

}


9.6 switch语句

switch语句实现多路分支。

  • switch语句包含0个或多个分支。
  • 每个分支以一个或多个分支标签开始。
switch (测试表达式)
{
case 条件1:
代码
break;
case 条件2:
.代码
break;
case 条件n:
....
break;
default:
    ...
  break;

  • 测试表达式在结构的顶端被求值。
  • 如果条件表达式的值等于某个条件的值,也就是等于分支标签中的常数表达式,那么跟在分支标签后的语句列表中的语句被执行,直到遇到break语句。
  • 每个分支必须为break语句结尾(或goto语句)
  • break语句把执行引向switch语句的结尾。
  • default段是可选的,但如果包括了,就必须包括一条break语句。

说明:与C和C++不同,每个分支,包括可选的default段,必须以break或return语句结束。在C#中,没有从一个分支到下一个分支的倒向(即不能有case的穿透现象)。

使用default段通常被认为是好习惯,因为它可以捕获潜在的错误。


分支标签

分支标签中跟在关键字case之后的表达式:

    • 必须是常数表达式,而且因此必须在编译期被编译器完全求值。
    • 必须与测试表达式类型相同。
尽管C#不允许从一个分支到另一个分支的倒向。
    • 可以把多个分支标签附加到任意分支。
    • 跟在和一个分支关联的语句列表后面,在下一个标签之前,必须是一个break或goto语句,除非在这两个分支标签之间没有插入可执行语句。

9.7 循环

while(TestExpr)

{

//代码段

}


9.8 do循环

do

{

//代码段

}

whle(TestExpr);


do循环有几个特征,使它与其他控制流结构分开。它们如下:

  • 循环体Statement总是至少被执行一次,即使TestExpr初始为false。
  • 在测试表达式的关闭圆括号之后需要一个分号。

9.9 for循环
只要测试表达式在循环体顶端计算时返回true,for循环结构就会执行循环体。for循环的主事法如下所示:
  • 在循环的开始,Initializer被执行一次。
  • 然后TestExpr被求值。
  • 如果它返回true,Statement被执行,接着是IterationExpr。
  • 控制然后回到循环的顶端,TestExpr再次被求值。
  • 只要TestExpr返回true,Statement和IterationExpr都将被执行。
for(Initializer;TestExpr;IterationExpr)
{
//代码段
}

语句中的一些部分是可选的。

  • Initializer、TestExpr和IterationExpr都是可选的。它们的位置可以空着。如果TestExpr位置是空的,那么测试被假定返回true。因此,如果程序要避免进入无限循环,必须有某种其他退出该语句的方法。
  • 分号是必须的。

for语句中变量的有效范围

任何声明在initializer中的变量只在该for语句的内部可见。


初始化语句和迭代表达式中的多表达式

初始语句和迭代表达式都可以包含多个表达式,只要它们用逗号隔开。


9.10 跳转语句

当控制流到达跳转语句时,程序执行被无条件转移到程序的另一部分。跳转语句有:

  • break
  • continue
  • return
  • goto
  • throw
break语句

break导致执行跳出最内层封装的语句(innermost enclosing statement)。

可被用在下列语句类型中:

    • switch
    • for
    • foreach
    • while
    • do
continue语句
continue语句导致程序执行转到下列类型循环的最内层封装循环(innermost enclosing statement)的顶端:
    • while
    • do
    • for
    • foreach

9.11 标签语句

标签语句由一个标识符后面跟着一个冒号再跟着一条语句组成。它有下面的形式。

Identifier:Statement

标签语句的执行完全如同标签不存在一样,并仅执行Statement部分。

  • 给语句增加一个标签允许控制从代码的另一部分转移到该语句。
  • 标签语句只允许用在块内部。
标签
标签有它们自己的声明空间,所以标签语句中的标识符可以是任何有效的标识符,包括可能已经在重叠的范围内声明的标识符,比如本地变量或参数名。
然而,也有限制。该标识符不能是:
    • 在重叠范围内和另一个标签标识符相同。
    • 关键字。
标签语句的范围
标签语句不能从它的声明所在的块的外部可见(或可访问)。标签语句的范围是:
    • 它声明所在的块。
    • 任何嵌套在该块内部的块。

9.12  goto语句
goto语句无条件转移控制到一个标签语句。它的一般形式如下,其中Identifier是标签语句的标识符:
goto Identifier;

goto语句必须在标签语句的范围之内。
  • goto语句可以跳到它本身所在块内的任何标签语句,或跳出到任何它被嵌套的块内的标签语句。
  • goto语句不能跨入任何嵌套在该语句本身所在块内部的任何块。
警告:使用goto语句是非常不好的,因为它会导致弱结构化的、难以调试和维护的代码。Edsger Dijkstra在1968年给Communication of the ACM的信,标题为:“Go To Statement Considered Harmful”,是对计算机科学非常重要的贡献。它是首先发表的描述使用goto语句的缺陷的文章之一。

goto语名在在switch语句内部
还有另外两种goto语句的形式,用在switch语句内部。这些goto语句把控制转移到switch语句内部相应命名的分支标签。
goto case  ConstantExpression;
goto default;

9.13 using语句

某些类型的非托管对象有数量限制或很耗费系统资源。重要的是在代码使用完它们后,尽可能快地释放它们。using语句有助于简化该过程并确保这些资源被适当地处置。

资源是一个实现System.IDisposable接口的类或结构。IDisposable接口含有一个名称为Dispose的方法。

使用资源的阶段由以下部分组成:

  • 分配资源。
  • 使用资源。
  • 处置资源。
资源的包装使用
using语句帮助减少意外的运行时错误带来的潜在问题,它整洁地包装了资源的使用。
有两种形式的using语句。第一种形式如下:
    • 圆括号内的代码分配资源。
    • statement是使用资源的代码。
    • using语句隐式产生处置该资源的代码。
using (ResourceType Identifier = Expression) Statement
意外的运行时错误称为异常,处理可能的异常的标准方法是把可能导致异常的代码放进一个try块中,并把任何无 论有没有异常必须执行的代码放进一个finally中。
这种形式的using语句确实是这么做的。它执行下列内容:
    • 分配资源。
    • 把Statement放进try块。
    • 创建资源的Dispose方法的调用,并把它放进finally块。
多个资源和嵌套
using语句还可以被用于相同类型的多个资源,资源声明用逗号隔开。
语法如下:
using(ResourceType Id=Expr1,Id2=Expr2,...)EmbeddedStatement
using语句还可以被嵌套

using语句的另一种形式
using语句的另一种形式如下:
using (Expression) EmbeddedStatement
在这种形式中,资源在using语句之前声明。

虽然这种形式也能确保对资源的使用结束后Dispose方法总是被调用,但它不能防止你在using语句已经释放了它的非托管资源之后使用该资源,把它留在一种不一致的状态。因此它提供了较少的保护,而且不推荐使用。


9.14 其他语句

在其他章中阐述的语句
语句描述相关章节
Checked,unchecked这些语句控制溢出检查上下文第18章
Foreach该语句遍历一个集合的每个成员第14章和第20章
try,throw,finally这些语句和异常有关第11章
return该语句返回控制到调用函数成员,而且还能返回一个值第5章
yield该语句用于迭代第20章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值