(三)CSharp-方法

一、实例字段和局部变量

实例字段局部变量
生存期从实例被创建时开始,直到实例不再被访问时结束从它在块中被声明的那一刻开始,在块完成执行时结束
隐式初始化初始化成该类型的默认值没有隐式初始化。如果变量在使用之前没有被赋值,编译器就会产生一条错误消息
存储区域由于实例字段是类的成员,所以所有字段都存储在堆里,无论它们是值类型的还是引用类型的值类型:存储在栈里 引用类型:引用存储在栈里,数据存储在堆里

1、使用 var 关键字条件:

  • 只用于局部变量,不能用于字段;
  • 只能在变量声明中包含初始化时使用;
  • 一旦编译器推断变量的类型,它就是固定且不能更改的。

2、局部常量

常量的两个特征:

  • 在声明时必须初始化;
  • 在声明后不能改变;
const Type Indentifier = Value;

声明特点:

  • 类型前添加 const
  • 必须初始化语句。初始化值必须在编译期决定。可以是 null 引用,但不能是某对象的引用。(对象的引用是在运行时决定的)

二、控制流

表 - 控制流描述

类型关键字描述
选择语句 if有条件地执行一条语句。
选择语句 if…else有条件地执行一条或另一条语句。
选择语句 switch有条件地执行一组语句中的某一条。
迭代语句 for 循环在顶部测试
迭代语句 while 循环在顶部测试
迭代语句 do 循环在底部测试
迭代语句 foreach 循环为一组中每个成员执行一次
跳转语句 break跳出当前循环
跳转语句 continue到当前循环的底部
跳转语句 goto到一个命名的语句
跳转语句 return返回到调用方法继续执行

三、形参和实参

形参: 声明在方法的参数列表中
实参: 用于初始化形参的表达式或变量
自动初始化

变量类型存储位置自动初始化用途
局部变量栈或者栈和堆用于函数成员内部的局部计算
类字段类的成员
结构字段栈或堆结构的成员
参数用于把值传入或传出方法
数组元素数组的成员

1、dynamic关键字

在编译时,编译器不会对 dynamic 类型的变量做类型检查。相反,它将与该变量及该变量的操作有关的所有信息打包。在运行时,会对这些信息进行检查,以确保它与变量所代表的实际类型一致。否则,将在运行时抛出异常。

2、值参数

参数以不同的方式从方法传入或传出数据,称为值参数。
使用值参数时,通过将实参的值复制到形参的方式把数据传递给方法。方法被调用时,系统执行如下操作。

  • 在栈中为形参分配空间。
  • 将实参的值复制给形参。

3、引用参数

引用参数

  • 使用引用参数时,必须在方法的声明和调用中都使用 ref 修饰符。
  • 实参必须是变量,在用作实参前必须被赋值。如果是引用类型变量,可以赋值为一个引用或 null。
    引用参数具有以下特征:
  • 不会在栈上为形参分配内存。
  • 形参的参数名将作为实参变量的别名,指向相同的内存位置。

4、引用类型作为值参数和引用参数

在方法内设置引用类型形参时:

  • 将引用类型对象作为值参数传递
    如果在方法内创建一个新对象并赋值给形参,将切断形参与实参之间的关联,并且在方法调用结束后,新对象也将不复存在。
    (注意:在方法内,对象所引用的数据成员会有改变)
  • 将引用类型对象作为引用参数传递
    如果在方法内创建一个新对象并赋值给形参,在方法结束后该对象依然存在,并且是实参所引用的值。

四、参数数组

特点:

  • 在一个参数列表中只能有一个参数数组
  • 如果有,它必须是列表中的最后一个;
    由于参数数组表示的所有参数必须是同一类型

声明参数数组时:

  • 在数据类型前使用 params 修饰符。
  • 在数据类型后放置一组空的方括号;
void ListInts(params int[] inVals)
{

}
调用者
void Fun()
{
int[] intArray = {1,2,3};
ListInts(intArray);
//或者
ListInts(10,20,30);
}

参数类型总结

参数类型修饰符是否在声明时使用是否在调用时使用执行
系统把实参的值赋值到形参
引用ref形参是实参的别名
输出out仅包含一个返回的值。形参是实参的别名
数组params允许传递可变数目的实参方法

五、ref 局部变量 和 ref 返回

//出自《C#图解教程》 -第六章方法-6.17的例子,本书能够输出结果。
//可同样的代码,在自己的编译器里运行会报错,提示“类结构或接口成员声明中的标记无效”
//这个语法,真的可以声明一个 return ref 的函数吗?(很不理解!!!)
 class Simple
    {
        private int Score = 5;
        public ref int RefToValue()
        {
            return ref Score;
        }

    }

后面的例子我也没法继续学习了。同样的代码,在编译器里也是报错的。并且,在网上没有查到更多相关的资料。(微软开发文档也没有找到)不过也看到有些网友实现 了rerurn ref 的例子。这反而让我更困惑了!

六、栈帧

在调用方法的时候,内存从栈的顶部开始分配,保存和方法关联的一些数据项,这块内存叫作方法的栈帧(stack frame)。

1、栈帧包含的内存保存:

  • 返回地址,也就是在方法退出的时候继续执行的位置。
  • 分配内存的参数,也就是方法的值参数,还可能是参数数组(如果有的话)。(本书应该写漏了,我认为分配内存还包括局部变量)
  • 和方法调用相关的其他管理数据项。(不太懂?数据项包括局部变量吗,还是其他的数据项)

2、在方法调用和时,整个栈帧都会压入栈。
3、在方法退出的时候,整个栈帧都会从栈上弹出。弹出栈帧有的时候也叫作栈展开(unwind)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值