C#方法的声明和使用
在 C# 中,方法的作用主要是方便代码的重复使用。
例如,我们在玩经典的《超级玛丽》游戏时,想一想,什么时候游戏会结束?至少有 3 种情况,碰到障碍物、被吃掉、直接掉下去,如下图所示。
图 1 结束游戏的3种情况
在遇到这 3 种情况时,游戏都会结束。如果用程序实现,那么当出现这 3 种情况时,就需要有相同的代码去结束游戏,这样就会造成结束游戏的代码重复写 3 次,而且后期一旦再有其他情况,还需要重复写。
遇到这种情况时,就可以将结束游戏的代码封装成一个方法,当遇到需要结束游戏的情况时,直接调用这个方法即可。接下来对方法进行讲解。
声明方法的基本格式如下:
一个方法的签名由它的名称以及参数的个数、修饰符和类型组成,返回值类型不是方法签名的组成部分,参数的名称也不是方法签名的组成部分。
例如,定义一个 ShowInfo 方法,用来输出飞机的坐标信息,代码如下:
例如,定义一个返回值类型为 int 的方法,就必须使用 return 返回一个 int 类型的值,代码如下:
图 2 方法无返回值时出现的错误提示
图 3 参数调用
参数就是定义方法时,在方法名后面的小括号中定义的“变量”。C# 中的方法参数主要有 4 种,分别为值参数、ref 参数、out 参数和 params 参数,下面分别进行讲解。
在调用方法时可以给该方法传递一个或多个值,传给方法的值叫作实参。在方法内部,接收实参的变量叫作形参,形参在紧跟着方法名的括号中声明,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。
形参和实参示意图如下图所示。
图 4 形参和实参示意图
例如,定义一个 Add 方法,用来计算两个数的和。该方法中有两个形参,但在方法体中,对其中的一个形参 x 执行加 y 操作,并返回 x;在 Main 方法中调用该方法,为该方法传入定义好的实参;最后分别显示调用 Add 方法执行计算之后的结果和实参 x 的值。
代码如下:
如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么在方法中对参数的修改会体现在原有的数组或者其他引用类型上。
例如,定义一个 Change 方法,该方法中有一个形参,类型为数组类型;在方法体中,改变数组中索引为 0、1、2 这 3 处的值;在 Main 方法中定义一个一维数组并初始化,然后将该数组作为参数传递给 Change 方法,最后输出一维数组的元素。
代码如下:
修改上面例子中的 Add 方法,将形参 x 定义为 ref 参数,然后再输出调用 Add 方法之后的实参 x 的值。代码如下。
使用 ref 参数时,需要注意以下几点:
例如,继续修改 Add 方法,在 Add 方法中添加一个 out 参数 z,并在 Add 方法中使用 z 记录 x 与 y 的相加结果;在 Main 方法中调用 Add 方法时,为其传入一个未赋值的实参变量 z,最后输出实参变量 z 的值。代码如下:
1、一个方法中有多个相同类型的参数
例如,定义一个 Add 方法,用来计算多个 int 类型数据的和。在具体定义时,将参数定义为 int 类型的一维数组,并指定为 params 参数;在 Main 方法中调用该方法,分别为该方法传入多个 int 类型的数据和一个一维数组,并输出计算结果。代码如下:
例如,我们在玩经典的《超级玛丽》游戏时,想一想,什么时候游戏会结束?至少有 3 种情况,碰到障碍物、被吃掉、直接掉下去,如下图所示。
图 1 结束游戏的3种情况
在遇到这 3 种情况时,游戏都会结束。如果用程序实现,那么当出现这 3 种情况时,就需要有相同的代码去结束游戏,这样就会造成结束游戏的代码重复写 3 次,而且后期一旦再有其他情况,还需要重复写。
遇到这种情况时,就可以将结束游戏的代码封装成一个方法,当遇到需要结束游戏的情况时,直接调用这个方法即可。接下来对方法进行讲解。
方法的声明
方法在类或结构中声明,声明时应该指定访问修饰符、返回值类型、方法名及方法参数。其中,方法参数放在方法名后面的小括号中,并用逗号隔开,小括号中没有内容时表示声明的方法没有参数。声明方法的基本格式如下:
[访问修饰符] 返回值类型 方法名(参数列表) { //方法的具体实现; }其中,访问修饰符可以是 private、public、protected、internal 中的任何一个,也可以省略,如果省略访问修饰符,则方法的默认访问级别为 private(私有),即只能在该类中访问;“返回值类型”指定方法返回数据的类型,可以是任何类型,如果方法不需要返回一个值,则使用 void 关键字;“参数列表”是用逗号分隔的类型、标识符,如果方法中没有参数,则“参数列表”为空。
一个方法的签名由它的名称以及参数的个数、修饰符和类型组成,返回值类型不是方法签名的组成部分,参数的名称也不是方法签名的组成部分。
例如,定义一个 ShowInfo 方法,用来输出飞机的坐标信息,代码如下:
public void ShowInfo() { Console.WriteLine("飞机的X坐标:" + x); Console.WriteLine("飞机的Y坐标:" + y); }如果定义的方法有返回值,则必须使用 return 关键字返回一个指定类型的数据。
例如,定义一个返回值类型为 int 的方法,就必须使用 return 返回一个 int 类型的值,代码如下:
public int ShowInfo() { Console.WriteLine("飞机信息"); return 1; }上面的代码中,如果将 return 1; 删除,会出现下图所示的错误提示。
图 2 方法无返回值时出现的错误提示
方法的参数
在调用方法时,有时需要向方法传递数据,这个传递的数据称为参数,如下图所示。图 3 参数调用
参数就是定义方法时,在方法名后面的小括号中定义的“变量”。C# 中的方法参数主要有 4 种,分别为值参数、ref 参数、out 参数和 params 参数,下面分别进行讲解。
在调用方法时可以给该方法传递一个或多个值,传给方法的值叫作实参。在方法内部,接收实参的变量叫作形参,形参在紧跟着方法名的括号中声明,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。
形参和实参示意图如下图所示。
图 4 形参和实参示意图
1) 值参数
值参数就是在声明时不加修饰符的参数,它表明实参与形参之间按值类型传递,即在方法中对值类型的形参的修改并不会影响实参。例如,定义一个 Add 方法,用来计算两个数的和。该方法中有两个形参,但在方法体中,对其中的一个形参 x 执行加 y 操作,并返回 x;在 Main 方法中调用该方法,为该方法传入定义好的实参;最后分别显示调用 Add 方法执行计算之后的结果和实参 x 的值。
代码如下:
private int Add(int x, int y) //计算两个数的和 { x = x + y; //对x执行加y操作 return x; //返回x } static void Main(string[] args) { Program pro = new Program(); //创建Program对象 int x = 30;//定义实参变量x int y = 40; //定义实参变量y Console.WriteLine("运算结果:" + pro.Add(x, y));//输出运算结果 Console.WriteLine("实参x的值:" + x); //输出实参x的值 Console.ReadLine(); }程序运行结果如下。
运算结果:70
实参x的值:30
如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么在方法中对参数的修改会体现在原有的数组或者其他引用类型上。
例如,定义一个 Change 方法,该方法中有一个形参,类型为数组类型;在方法体中,改变数组中索引为 0、1、2 这 3 处的值;在 Main 方法中定义一个一维数组并初始化,然后将该数组作为参数传递给 Change 方法,最后输出一维数组的元素。
代码如下:
class Program { public void Change(int[] i) { i[0] = 100; i[1] = 200; i[2] = 300; } static void Main(string[] args) { Program pro = new Program(); //创建Program对象 int[] i = { 0, 1, 2 }; pro.Change(i); for (int j = 0; j < i.Length; j++) { Console.WriteLine(i[j]); } Console.ReadLine(); } }程序运行结果如下。
100
200
300
2) ref参数
ref 参数使形参按引用传递(即使形参是值类型),其效果是在方法中对形参所做的任何修改都将反映在实参中。如果要使用 ref 参数,则方法声明和方法调用都必须显式使用 ref 关键字。修改上面例子中的 Add 方法,将形参 x 定义为 ref 参数,然后再输出调用 Add 方法之后的实参 x 的值。代码如下。
private int Add(ref int x, int y)//计算两个数的和 { x = x + y; //对x执行加y操作 return x; //返回x } static void Main(string[] args) { Program pro = new Program(); //创建Program对象 int x = 30; //定义实参变量x int y = 40; //定义实参变量y Console.WriteLine("运算结果:" + pro.Add(ref x, y));//输出运算结果 Console.WriteLine("实参x的值:" + x); //输出实参x的值 Console.ReadLine(); }程序运行结果如下。
运算结果:70
实参x的值:70
使用 ref 参数时,需要注意以下几点:
- ref 关键字只对跟在它后面的参数有效,而不是应用于整个参数列表。
- 在调用方法时,必须使用 ref 修饰实参;而且因为是引用参数,所以实参和形参的数据类型必须完全匹配。
- 实参只能是变量,不能是常量或者表达式。
- 在调用 ref 参数之前,一定要进行赋值。
3) out参数
out 关键字用来定义输出参数,它会使参数通过引用来传递,这与 ref 关键字类似。不同之处在于 ref 关键字要求变量必须在传递之前进行赋值,而使用 out 关键字定义的参数不用进行赋值即可使用。如果要使用 out 参数,则方法声明和方法调用都必须显式使用 out 关键字。例如,继续修改 Add 方法,在 Add 方法中添加一个 out 参数 z,并在 Add 方法中使用 z 记录 x 与 y 的相加结果;在 Main 方法中调用 Add 方法时,为其传入一个未赋值的实参变量 z,最后输出实参变量 z 的值。代码如下:
private int Add(int x, int y, out int z)//计算两个数的和 { z = x + y; //记录x+y的结果 return z; //返回z } static void Main(string[] args) { Program pro = new Program(); //创建Program对象 int x = 30; //定义实参变量x int y = 40; //定义实参变量y int z;//定义实参变量z Console.WriteLine("运算结果:" + pro.Add(x, y, out z));//输出运算结果 Console.WriteLine("实参z的值:" + z); //输出实参变量z的值 Console.ReadLine(); }程序运行结果如下:
运算结果:70
实参z的值:70
4) params参数
在定义方法时,如果遇到下面两种情况该怎么办:1、一个方法中有多个相同类型的参数
public void Func(int i,int j,int r,int t,int x,int y,int z)2、方法中的参数个数不固定
public void Func(int i,int j,int r...)例如,定义一个方法,需要处理 100 个 int 类型的参数,难道我们要在参数列表中定义 100 个 int 类型的参数呀?有 1 万个参数怎么办? C# 中提供了 params 参数来处理这种情况。params 参数可以修饰一个一维数组,用来指定在参数类型相同,但数量过多或者不确定时所采用的方法参数。
例如,定义一个 Add 方法,用来计算多个 int 类型数据的和。在具体定义时,将参数定义为 int 类型的一维数组,并指定为 params 参数;在 Main 方法中调用该方法,分别为该方法传入多个 int 类型的数据和一个一维数组,并输出计算结果。代码如下:
private int Add(params int[] x) //定义Add方法,并指定params参数 { int result = 0; //记录运算结果 for (int i = 0; i < x.Length; i++)//遍历参数数组 { result += x[i]; //执行相加操作 } return result; //返回运算结果 } static void Main(string[] args) { Program pro = new Program(); //创建Program对象 //输出运算结果 Console.WriteLine("{0}+{1}+{2}=" + pro.Add(20, 30, 40), 20, 30, 40); int[] test = { 20, 30, 40, 50, 60 }; Console.WriteLine("{0}+{1}+{2}+{3}+{4}=" + pro.Add(test),test[0], test[1],test[2],test[3], test[4]); Console.ReadLine(); }程序运行结果如下:
20+30+40=90
20+30+40+50+60=200
- 只能在一维数组中使用 params 参数;
- 不允许使用 ref 关键字或者 out 关键字修饰 params 参数;
- 一个方法最多只能有一个 params 参数。