C#图解教程学习笔记——方法

一、字段和本地变量、本地常量
字段:隶属于类的变量,即类的成员变量。
本地变量:于保存本地的或临时的计算数据,即局部变量。
本地常量:必须声明在块内部,声明时必须初始化,声明后不能改变。
实例字段与本地变量区别图解:

本地变量生存周期图解:

注:
  在C和C++中,可以先声明一个本地变量,然后在嵌套块中声明另一个同名本地变量。在内部范围,内部变量覆盖外部变量。然而,在C#中不管嵌套级别如何,都不能在第一个本地变量的有效范围内声明另一个同名本地变量。

二、类型推断和var关键字
若编译器能从初始化语句的右边推断出类型名,则可使用var关键字代替具体类型名。var不是特定的类型变量符号,它表示任何可以从初始化语句的右边推断出来的类型。
使用var的条件:
(1)只能用于本地变量,不能用于字段
(2)只能在变量声明中包含初始化时使用
(3)一旦编译器推断出变量的类型,它就是固定且不能更改的
注:
  var关键字不像JavaScript的var那样可以引用不同的类型。它是从等号右边推断出的实际类型的速记。var关键字并不改变C#的强类型性质。

三、值参数、引用参数、输出参数、参数数组、命名参数、可选参数
1. 值参数
使用值参数,通过将实参的值复制到形参的方式把数据传递给方法。方法被调用时,系统做如下操作:
(1)在栈中为形参分配空间。
(2)将实参的值复制给形参。
方法中对形参的修改是否会影响方法外的实参?
若实参是值类型,值被复制,产生一个独立的数据,此时形参和实参存储在内存不同位置,方法中对形参的修改不会影响方法外的实参;若实参是引用类型,则引用被复制,此时虽然形参和实参是两个存储在内存不同位置的引用,但是它们都指向堆内存中同一个数据对象,所以方法中对形参的修改会直接影响方法外的实参。
2. 引用参数
使用引用参数的要求:
(1)必须在方法的声明和调用时都使用ref修饰符。
(2)实参必须是变量,在用作实参前必须被赋值。如果是引用类型变量,可以赋值为一个引用或null。
示例:

与值参数不同,引用参数不会为形参在栈上分配内存,实际上形参的参数名将作为实参变量的别名,指向相同的内存位置,所以在方法的执行过程中对形参做的任何改变在方法完成后依然有效。
关于引用类型对象作为值参数和引用参数的区别?
(1)将引用类型对象作为值参数传递:如果在方法内创建一个新对象并赋值给形参,将切断形参与实参间的关联,并且在方法调用结束后,新对象也将不复存在。(实参与形参是存储在不同内存位置的两个引用)
(2)将引用类型对象作为引用参数传递:如果在方法内创建一个新对象并赋值给形参,在方法结束后该对象依然存在,并且是实参所引用的值。(实参与形参是存储在相同内存位置的同一引用)
3. 输出参数
输出参数用于从方法体内把数据传出到调用代码,它们的行为与引用参数非常类似。
输出参数有以下要求:
(1)必须在声明和调用中都使用 out 修饰符。
(2)和引用参数类似,实参必须是变量。
(3)在方法内部,输出参数在被读取前必须赋值。
(4)方法返回前,方法内任何返回路径都必须为所有输出参数进行赋值。
示例:

注:
  与引用参数相同的是,输出参数的形参就好像是实参的别名一样;与引用参数不同的是,变量在用作实参时可以不用先赋值。
4. 参数数组
参数数组允许零个或多个实参对应一个特殊的形参。
(1)限制与要求:
<1>在一个参数列表中只能有一个参数数组。
<2>如果有,它必须是列表中最后一个。
<3>由参数数组表示的所有参数都必须具有相同类型。
(2)声明与调用方法:
<1>声明示例:

<2>两种调用方法:
逗号分隔的该数据类型元素列表:
ListInts(10,20,30);
该数据类型元素的一维数组:
int[] intArray={1,2,3};
ListInts(intArray);
<3>编译器对数组参数的处理:
使用参数列表作为实参:
  接受实参列表,用它们在堆中创建并初始化一个数组。
  把数组的引用保存在栈中的形参里。
  如果在对应的形参数组位置没有实参,编译器会创建一个有零个元素的数组来使用。
使用数组变量作为实参:
  直接使用作为实参的数组,而不是重新创建一个。
5. 命名参数
C#允许我们使用命名参数(named parameter),只要显式指定参数名字,就可以以任意顺序在方法调用中列出实参。
示例:

6. 可选参数
可选参数就是我们可以在调用方法时包含这个参数,也可以省略。 为了表明名某参数可选,你需要在方法声明时为参数提供默认值。
示例:

(1)不是所有参数类型都可以作为可选参数。只要值类型的默认值在编译时可以确定,就可以使用值类型作为可选参数;只有在默认值是null时,引用类型才可以作为可选参数。
(2)所有必填参数必须在可选参数前声明。如果有params参数,必须在可选参数后声明。
(3)当有多个可选参数时,默认情况下只能省略后面几个。若实际调用情况不符合该规则,可以使用命名参数,指定参数名称进行传值。

四、方法重载
一个类中可以用一个以上的方法拥有相同名称,这叫方法重载(method overload)。使用相同名称的方法必须有一个和其他方法不同的签名(signature)。
方法的签名由下列信息组成:
(1)方法的名称
(2)参数的数目
(3)参数的数据类型和顺序
(4)参数修饰符
注:
  返回类型不是签名的一部分,形参名称也不是签名的一部分。

五、栈帧
调用方法时,内存从栈顶开始分配,保存和方法关联的一些数据项。这块内存叫做方法的栈帧(stack frame)。
栈帧内存包含以下内容:
(1)返回地址,即方法退出时继续执行的位置。
(2)参数分配的内存,也就是方法的值参数,或参数数组。
(3)各种和方法调用相关的其他管理数据项。
在方法调用时,整个栈帧会压入栈。
在方法退出时,整个栈帧从栈上弹出。弹出栈帧也叫栈展开(unwind)。
示例:

栈帧图示:

原文地址:https://www.cnblogs.com/wujuntian/p/10946964.html