目录
5.1 方法的结构
方法是一块具有名称的代码。可以使用方法的名称从别的地方执行代码,也可以把数据传入方法并接受数据输出。
如前一章所属,方法是类的函数成员。方法有两个主要部分,如图5-1所示:方法头和方法体。
- 方法头指定方法的特征,包括:
- 方法是否返回数据,如果返回,返回什么类型;
- 方法的名称;
- 那种类型的数据可以传递给方法或从方法返回,以及应如何处理这些数据。
- 方法体包含可执行代码的语句序列。执行过程从方法体的第一条语句开始,一直到整个方法结束。
下面的示例展示了方法头的形式。接下来阐述其中的每一部分。
例如,下面的代码展示了一个名称为MyMethord的简单方法,它多次轮流调用WriteLine方法。
尽管前面几章都描述了类,但是还有另外一种用户定义的类型,叫做struct,我们会在第10章中介绍。本章中介绍的大多数有关方法的内容同样适用于struct方法。
5.2 方法体内部的代码执行
方法体是一个块,是大括号起的语句序列(参考第二章)。块可以包含以下项目:
- 本地变量;
- 控制流结构;
- 方法调用;
- 内嵌的块。
图5-2展示了方法体及其组成的示例。
5.3 本地变量
和第4章介绍的字段一样 ,本地变量也保存数据。字段通常保存和对象状态有关的数据,而创建本地变量经常是用于保存本地的临时的计算数据。表5-1对比了本地变量和实例字段的差别。
下面这行代码展示了本地变量生明的语法。可选的初始化语句由等号和用于初始化的值组成。
- 本地变量的存在性和生存期仅限于它的块以及内嵌的块。
- 它从声明它的哪一点开始存在。
- 它再快完成执行时结束存在。
- 可以在方法体内任意位置声明本地变量,但必须在使用它们前声明。
下面的示例展示了两个本地变量的声明和使用。第一个是int类型,第二个是SomeClass类型变量。
5.3.1 类型推断和Var关键字
如果观察下面的代码,你会发现在声明的开始部分提供类型名时,你提供的时编译器能从初始化语句右边推断的信息。
- 在第一个变量声明中,编译器能推断出15是int型。
- 在第二个声明中,右边的对象创建表达式返回了一个MyExcellentClass类型的对象。
所以在这两种情况中,在声明的开始部分包括显示的类型名是多余的。
var关键字并不是特定类型变量的符号。它只是句法上的速记,在表示任何可以从初始化语句的右边推断出的类型。在第一个声明中,他是int的速记;在第二个声明中,他是MyExcellentClass的速记。前文中使用显示类型名的代码片段和使用var关键字的代码片段在语义上是等价的。
使用var关键字有一些重要条件:
- 只能用于本地变量,不能用于字段;
- 只能在变量声明中包含初始化时使用;
- 只能在变量声明包含初始化时使用;
- 一旦编译器推断出变量的类型,他就是固定且不能更改的。
5.3.2 嵌套块中的本地变量
方法体内部可以嵌套其他的块。
- 可以有任意数量的块,并且它们既可以是顺序的也可以更深层嵌套的。块可以嵌套到任和级别。
- 本地变量可以在嵌套块的内部声明,并且和所有的本地变量一样,它们的生存期和可见性仅限于声明它们的块及其内嵌的块。
图5-3阐述了两个本地变量的生存期,展示了代码和栈的状态。箭头标出了刚执行过的行。
- 变量var1声明在方法体中,在嵌套块之前。
- 变量var2声明在嵌套块内部。它从声明那一刻开始存在,直到声明它的那个块的尾部结束。
- 当控制传出嵌套块时,它的本地变量从栈中弹出。
5.4 本地常量
本地常量很想本地变量,只是一旦被初始化,它的值就不能改变了。如同本地变量,本地常量必须在块的内部。
常量的两个最重要的特征如下。
- 常量在声明时必须初始化。
- 常量在声明后不能改变。
常量的核心声明如下所示。语法与字段或变量的声明相同,除了下面内容。
- 在类型之前增加关键字const。
- 必须有初始化语句,初始化值必须在编译期决定,通常是一个预定义简单类型或由其组成的表达式。它还可以是null引用,但是不能是某对象的引用,因为对象的引用是在运行时决定的。
就像本地变量,本地常量声明在方法体或代码块里,在声明它的块结束的地方失效。列如,在下面的代码中,类型为内嵌类型double的本地常量在PI在方法DisplayRadii结束后失效。
5.5 控制流
方法包含了大部分组成程序行为的代码。剩余部分在其他的函数成员中,如属性和运算符。
术语控制流指的是程序从头到尾的执行流程。默认情况下,程序执行持续地从一条语句到下一条语句,控制流语句允许你改变执行的顺序。
在这一节,只会提及一些能用于代码的控制语句,第九章会详细阐述它们。
- 选择语句 这些语句可以选择哪条语句或语句块来执行。
- if 有条件的执行一条语句;
- if...else 有条件地执行一组语句的的某一条。
- switch 有条件地执行一组语句中的某一条。
- 迭代语句 这些语句可以在一个语句块上循化或迭代。
- for 循环-------在顶部测试;
- while 循环-------在顶部测试;
- do 循环-------在顶部测试;
- foreach 为每一组成员执行一次。
- 跳转语句 这些语句可以让你从代码块或方法体内部的一个地方跳到另一个地方。
- break 跳出循环;
- continue 到当前循环的底部;
- goto 到另一个命名的语句;
- return 返回到调用方法继续执行。
例如,下面的方法展示了两个控制流语句,先别管那些细节。
5.6 方法调用
可以从方法体的内部调用其他方法。
- 英文call(调用)方法和invoke方法是同义的。
- 调用方法时要使用方法名并带上参数列表。参数列表将稍后讨论。
例如下面的类声明了一个名称为PrintDateAndTime的方法,在Main方法内会调用该方法。
图5-4阐明了调用方法时的动作顺序。