方法用来定义类可执行的操作,它是包含一系列语句的代码块。从本质上来讲,方法就是和类相关联的动作。
一、方法的声明
方法在类或结构中声明,声明时需要指定访问级别、返回值、方法名称及方法参数。方法参数在括号中,并用逗号隔开。如果括号中没有内容,则表示声明的方法没有参数。
定义一个方法时,从根本上说是在声明它的结构的元素。在 C# 中,定义方法的语法如下:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
访问权限修饰符 返回值 方法名 参数列表
{
Method Body//方法的具体实现
}
- Access Specifier 修饰符:可以是private、public、protected、internal中的任何一个。 这个决定了变量或方法对于另一个类的可见性。
- Return type 返回值:指定方法返回数据的类型(可以是任何类型),如果方法不需要返回值,则使用void关键字。
- Method name 方法名称:是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
- Parameter list 参数列表:用逗号分隔的类型、标识符,如果方法中没有参数,则参数列表为空。使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
- Method body:方法主体,包含了完成任务所需的指令集。
注意点:每一个 C# 程序至少有一个带有 Main 方法的类。 方法的定义必须在某个类中,定义方法时如果没有声明访问修饰符,则方法的默认访问权限为private。
如果定义的方法有返回值,则必须使用return关键字返回一个指定类型的数据。
public int Show()
{
Console.WriteLine("方法");
return 99;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _20220803_1
{
class Program
{
static void Main(string[] args)
{
int x = 1;
for (int i = 7; i > 0; i--)
x *= i;
Console.WriteLine("7! ={0}", x);
}
}
}
//输出结果为:7! =5040
二、方法的传递参数
在调用方法时可以给该方法传递一个或多个值,传给方法的值称为实参;在方法内部,接受实参的变量成为形参。形参在紧跟着方法名的括号中声明,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。
C#中的方法的参数主要有4中:值参数、ref参数、out参数、params参数。
1、值参数
值参数是在声明时不加修饰的参数,它表明实参与形参之间按值传递。当使用值参数的方法被调用时,编译器为形参分配存储单元,然后将对应的实参复制到形参中。由于是值类型的传递方式,所以在方法中对值类型的形参的修改并不会影响实参。
2、ref参数
ref参数适用形参按引用传递(即使形参为值类型),其效果是,在方法中对形参所做的任何更改都将放映在实参中。如果要使用ref参数,则方法声明和方法调用都必须是显式使用ref关键字。
3、out参数
out关键字用来定义输出参数,它会导致参数通过引用来传递,这与ref关键字类似,不同之处在于,使用ref关键字要求变量必须在传递之前进行赋值,而使用out关键字定义的参数不用进行赋值即可使用。如果要使用out参数,则方法声明和方法调用都必须显式适用out关键字。
4、params参数
在声明方法时,如果有多个相同类型的参数,则可以定义为params参数。params参数是一个一维数组,主要用来指定在参数数目可变时所采用的方法参数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _20220802_3
{
class Program
{
private int Add(int x,int y)
{
x = x + y;
return x;
}
private int Add(ref int x,int y)
{
x = x + y;
return x;
}
private int Add(int x,int y,out int z)
{
z = x + y;
return z;
}
private int Add(params int[] x)
{
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();
int x = 30;
int y = 40;
Console.WriteLine("值参数的使用:" + pro.Add(x, y));
Console.WriteLine("值参数中实参x的值:" + x);
Console.WriteLine("ref参数的使用:" + pro.Add(ref x, y));
//输出ref参数方法中实参x的值
Console.WriteLine("ref参数中实参x的值:" + x);
Console.WriteLine("out参数的适用:" + pro.Add(x, y, out int z));
Console.WriteLine("params参数的使用:" + pro.Add(20, 30, 40, 50, 60));
}
}
}
方式 | 描述 |
---|---|
按值参数传递 | 这种方式复制参数的实际值给函数的形式参数,实参和形参使用的是两个不同内存中的值。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。 |
按引用参数传递 ref |
这种方式复制参数的内存位置的引用给形式参数。这意味着,当形参的值发生改变时,同时也改变实参的值。 |
按输出参数传递 out |
这种方式可以返回多个值。 |
按参数数组传递 params |
可以传递数组。 |
按值传递参数:这是参数传递的默认方式。在这种方式下,当调用一个方法时,会为每个值参数创建一个新的存储位置。实际参数的值会复制给形参,因此,实参和形参使用的是两个不同内存中的值。所以,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。
按引用传递参数:引用参数是一个对变量的内存位置的引用。当按引用传递参数时,与值参数不同的是,它不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置。
按输出传递参数:用户自定义的方法一般可以通过return语句返回一个值。如果希望方法能返回多个值,可以按照输出参数的方式进行传递参数。对于输出参数来说,调用方提供的实参的初始值并不重要,除此之外,输出参数遇引用参数类似。输出参数是用out修饰符声明的。即输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
按参数数组传递:当声明一个方法时,用户 不能确定要传递的参数个数时,可使用params关键字来定义。在C#中使用参数数组可以简化代码,因为在调用代码时就可以不必传递数组,而是传递同类型的几个参数。
三、方法的分类
方法分为静态方法和实例方法。其中使用static修饰符生命的方法称为静态方法,而不适用static修饰符声明的方法称为实例方法。
1、静态方法:静态方法不对特定实例进行操作,并且只能访问类中的静态成员,而且不能使用实例成员。访问静态方法时可以直接访问,也可以使用类名而不需要创建对象,也不能用对象名来引用。
2、实例方法:对特定实例进行操作,并且能够访问静态成员和实例成员。在调用实例方法的实例上,可以通过this显式地访问该实例。而在静态方法中引用this是错误的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _20220803_2
{
class Program
{
int exampleVer;//实例成员
static int staticVer;//静态成员
void exampleMethod()//实例方法
{
//在实例方法中,可以访问静态成员,也能访问实例成员
exampleVer = 111;
staticVer = 222;
Console.WriteLine("实例成员:{0}",exampleVer);
Console.WriteLine("静态成员:{0}", staticVer);
}
static void staticMethod()//静态方法
{
//在静态方法中,可以访问静态成员,但是不能访问实例成员
staticVer = 555;
Console.WriteLine("静态成员:{0}", staticVer);
}
static void Main(string[] args)
{
//访问静态方法
//调用静态方法有两种,一种可以直接调用,另一种是使用类名
staticMethod();//方法一
Program.staticMethod();//方法二
//访问实例方法
Program p = new Program();
p.exampleMethod();
}
}
}
//输出结果为:
//静态成员:555
//静态成员:555
//实例成员:111
//静态成员:222
四、构造函数与方法之间的区别
构造函数首先在定义上必须以类名为名称,不能有返回值。在使用时必须通过new关键字调用。构造函数的作用是用来配置一个新的对象。因为实际上对象不是你负责分配内存的,你在构造函数内完成的是根据你的需要进行的初始化和额外工作。构造函数返回的就是这个新对象的引用。
方法要么作为静态方法通过类名调用,要么通过实例调用实例方法。当然你也可以定义一些方法来构造新对象,但反过来构造函数不能完成方法的很多工作。
五、外部方法
当方法声明包含extern修饰符时,称该方法为外部方法。外部方法是在外部实现的,变成语言通常是适用C#以外的语言。外部方法不可以是泛型。
extern修饰符通常与“Dll Import”属性一起使用,从而使外部方法可以有DLL(动态链接阵)实现。执行环境可以支持其他用来提供外部方法实现的机制。当外部方法包含“Dll Import”属性时,该方法声明必须要包含一个static修饰符。
using System;
using System.Runtime.InteropServices;
namespace _20220803_3
{
class Program
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main(string[] args)
{
Console.Write("请输入姓名:");
string name = Console.ReadLine();
return MessageBox(0, "您好:" + name + "\n\n" + "欢迎您!","信息提示",0);
}
}
}
//这里需要注意的是对话框是利用return强行弹出的,所以需要将Main方法改为有返回值
五、方法的重载
方法的重载是指方法名相同,但参数的数据类型、个数或顺序不同的方法。只要类中有两个以上的同名方法,但是使用的参数类型、个数或顺序不同(即这些方法具有唯一的签名),在调用时,编译器就可判断在哪种情况下调用那种方法。
决定方法是否构成重载有三个条件 1、在同一个类中 2、方法名相同 3、参数列表不同 |
备注:在定义重载方法时,需要注意一下两点:①重载方法不能仅在返回值类型上不同,因为返回值类型不是方法签名的一部分。②重载方法不能仅根据参数是否声明为ref、out或params来区分。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _20220803_4
{
class Program
{
static void writeArea(int radius)
{
double area = System.Math.PI * radius * radius;
Console.WriteLine("圆形面积为:{0}", area);
}
static void writeArea(int l,int w)
{
int area = l * w;
Console.Write("矩形面积为:{0}", area);
}
static void Main(string[] args)
{
writeArea(5,7);
writeArea(12);
}
}
}
//结果为:矩形面积为:35圆形面积为:452.38934211693
六、Main方法
Main方法是程序的入口点。程序从这里开始,也是从这里结束。C#的Main方法必须是一个类的静态成员。Main方法可以是void类型,也可以是非void类型,并可以接受字符串数组形式的命令行参数。
1、Main方法的执行过程
当程序在执行编写的源代码时,会先找到Main方法,然后开始执行Main方法中“{”开始后的第一句代码,并依次执行。如果遇到Main方法中有调用其他方法时,便会根据方法名称找到定义方法的代码,然后执行这个方法内的代码,执行完成后,再返回到Main方法继续执行,直到遇到Main方法的结束符“}”,执行程序结束。
2、Main方法的四种表现形式
①静态的无返回值的Main方法。
static void Main()
②静态的有返回值的Main方法。
static int Main()
③静态的无返回值,并且有参数的Main方法。
static void Main(string[] args)
④静态的有返回值,并且有参数的Main方法。
static int Main(string[] args)
终上所述:上述有返回值int时,可以用于表示应用程序的终止方式,通常用一种错误提示。一般情况下,返回“0”表示程序“正常”终止(即应用程序执行完毕,并安全终止)。
Main的可选参数args是从应用程序的外部接受信息的方法,这些信息在运行应用程序时以命令行参数的形式指定。
备注:①当创建一个项目的时候,编译器会默认创建一个第三种形式的Main方法,并且默认使用这个Main方法。
②在一个程序中,Main方法只能有一个,并且该方法的位置不必固定,C#编译器找到Main方法,并将其作为这个程序的入口。
③在编写程序时,尽量不要修改编译器自动生成的Main方法。