C#-4 方法
一 何为方法
方法是一块具有名称的代码,是类的函数成员。
方法主要分为方法头和方法体。
void Method()
{
语句1;
语句2;
}
二 类型推断和var关键字
var sum = 15;
var myClass = new MyClass();
var关键字是句法上的速记,表示任何可以从初始化语句右边判断出的类型。
三 方法调用
var myClass = new MyClass();
myClass.Show();
四 返回值
方法可以向调用代码返回一个值,返回的值被插入到调用代码中发起调用的表达式所在的位置。
- 如果方法不返回值,必须声明为void
- 如果方法返回值,则必须声明一个返回类型
声明了返回类型的方法,必须在其方法体中使用由return关键字构成的表达式来返回一个值。
五 参数
5.1 形参
形参是本地变量,它声明在方法的参数列表中。
参数列表中可以有任意数量的形参,用逗号隔开。
形参在整个方法体内使用。
5.2 实参
当代码调用一个方法时,形参的值必须在方法的代码开始执行之前被初始化
- 用于初始化形参的表达式或变量成为实参
- 实参位于方法调用的参数列表中
- 每一个实参必须与对应形参的类型相匹配,或是编译器能实现隐式转换
六 值参数
使用值参数,通过将实参的值复制给形参的方式把数据传递给方法。
方法被调用时,系统在栈中为形参分配空间,将实参的值复制给形参。
七 引用参数
使用引用参数,必须在方法的声明和调用中使用ref修饰符。
void Method(ref int val)
{ ... }
使用引用参数,实参必须是变量,在用作实参前变量必须被赋值。如果是引用类型变量,可以赋值为一个引用或null。
对于值参数,系统在栈上为形参分配内存,而引用参数则不同,它有如下特征:
- 不会为形参在栈上分配内存;
- 形参的参数名将作为实参变量的别名,指向相同的内存地址。即在方法的执行过程中对形参的任何改变就如同对实参的改变。
八 引用类型作为值参数和引用参数
对于一个引用类型的对象,无论是将其作为值参数传递或引用参数传递,都可以在方法内部对该对象的成员进行操作。
- 将引用类型对象作为值参数传递时:如果在方法内部实例一个新对象并赋值给形参,将切断形参和实参之间的关联,并在方法调用结束后,新对象也将不复存在;
- 将引用类型对象作为引用参数传递时:如果在方法内部实例一个新对象并赋值给形参,在方法结束后该对象仍然存在,并且是实参所引用的值。
九 输出参数
输出参数用于从方法体内部把数据传到调用代码,使用out修饰符。
void Method(out int val)
{ ... }
与引用参数类似,输出参数的形参担当实参的别名,形参和实参都是同一块内存位置的名称。
在方法内部,输出参数在被读取之前必须被赋值,这意味着参数的初始值是无关的,且没必要在方法调用前为实参赋值。
在方法返回之前,方法内部贯穿的任何可能路径都必须为所有输出参数进行一次赋值。
十 参数数组
void Method(params int[] arrayInt)
{ ... }
//调用方式1
Method(10,20,30);
//调用方式2
int[] arrayInt = {10,20,30};
Method(arrayInt);
- 在一个参数列表中只能有一个参数数组;
- 如果有,它必须是列表中的最后一个;
十一 参数类型总结
十二 方法重载
一个类中可以有一个以上的方法拥有相同的名称,这叫做方法重载 method overload。
使用相同方法的名称必须有一个和其他方法不同的签名。
方法的签名有下列信息组成:
- 方法的名称;
- 参数的数量;
- 参数的数据类型和数量;
- 参数修饰符;
需要注意的是,返回类型不是签名的一部分!
十三 命名参数
class MyClass
{
public int Calc(int a, int b, int c)
{
return a + b + c;
}
static void Main()
{
var myClass = new MyClass();
var sum = myClass.Cals(c:2, a:4, b:3); //使用命名参数,可以显示指定参数名字来赋值
}
}
十四 可选参数
使用可选参数,可以让我们在调用方法的时候省略这个参数。
为了表明某个参数是可选的,需要在方法声明时为参数提供默认值。
class MyClass
{
public int Calc(int a, int b = 3)
{
return a + b;
}
static void Main()
{
var myClass = new MyClass();
var sum1 = myClass.Cals(2);
var sum2 = myClass.Cals(2,10);
Console.WriteLine($"sum1:{sum1},sum2:{sum2}"); //输出 sum1:5,sum2:12
}
}
十五 栈帧
局部变量(本地变量)和参数是位于栈上的。
在调用方法时,内存从栈的顶部开始分配,保存和方法相关联的一些数据项,这块内存叫做方法的栈帧 stack frame
栈帧包含:
- 返回地址,也就是在方法退出时继续执行的位置;
- 这些参数分配的内存,也就是方法的值参数,或参数数组;
- 各种和方法调用相关的管理数据项;
在方法调用时,整个栈帧都会压入栈。方法退出时,整个栈帧从栈上弹出。
十六 递归
方法调用自身,叫做递归。
__ 以 上 __