1.ref、out:参数传递的两种方式
ref:引用传递
using System;
namespace CalculatorApplication
{class NumberManipulator{public void swap(ref int x, ref int y){int temp;temp = x; /* 保存 x 的值 */x = y; /* 把 y 赋值给 x */y = temp; /* 把 temp 赋值给 y */}static void Main(string[] args){NumberManipulator n = new NumberManipulator();/* 局部变量定义 */int a = 100;int b = 200;Console.WriteLine("在交换之前,a 的值: {0}", a);Console.WriteLine("在交换之前,b 的值: {0}", b);/* 调用函数来交换值 */n.swap(ref a, ref b);Console.WriteLine("在交换之后,a 的值: {0}", a);Console.WriteLine("在交换之后,b 的值: {0}", b);Console.ReadLine();}}
}
out: 输出传参
假设在函数调用前变量a的值为5;
此函数的实现使用输出传参,在方法内第一次修改a=1,第二次修改a=2,第三次修改为a=3,那么a的值会在执行此函数后为3;
unity中的射线检测的第三个参数就是通过输出值传递被击中
物体的信息
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance);
还有一种就是最普通的值传递;
2.如何给bool赋值null
有些类型不能为空值,int,bool,float等;
使用"?"可让它们变成可空类型
赋值方法 bool? a=null;
a从bool类型的值变为可空bool值;
3."??"运算符
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值
例子:a=b??c 如果b等于null则a等于c(不管c的值是不是null)
4、交错数组
5、数组作为参数的两种方式
函数的参数中有数组时,可以传递数组的指针和将数组整体作为参数.
数组指针作为参数:
数组整体作为参数:
需要 在方法定义时配上关键字params;
6.结构体
与c和c++的结构体有所不同,参考文档
结构体的对象存储在栈中,适合体积小且简单的类型,访问速度快。
类的对象存储在堆中,适合体积大且复杂的语句块,但访问速度慢,栈中只存有对象的引用。
例如:
有一个类是Book类, 执行语句Book a;
a只是Book类的一个引用还没有分配内存,a在栈中。
当a=new Book()时,才为a分配了一个对象,这个对象在堆中,a作为内存位置的引用还是在栈中;
7.枚举(enum)
作用就是获取一个列表内成员在当前列表的序号,从0开始;
8.访问修饰符
用于封装后对封装数据的权限设置
五种:public,private,protected,Internal,protected Internal.
前三个和c++没啥区别;
类的默认就是Internal,也就是所有程序里都可以用这个类;
protected Internal“访问限于当前程序集或派生自包含类的类型”,目前没看见过这个;
9.类的成员函数
构造函数+析构函数+其他函数
构造函数:无返回值(也没有void),和类同名,默认无参数,可以手动实现带参构造;
析构函数:和类同名,前面带一个 “~”,无法继承无法重载,在类被销毁时调用;
2023.12.6补充:
除了构造函数,类的成员函数默认都为private;
10.静态成员
有点像单例,同一个类的对象再怎么多,这个类的静态成员的实例都不会随着对象的生成而增多,永远只有一个;
静态成员在对象生成前就已经存在了;
所以可以直接通过类名来访问静态成员;
而且静态函数只能访问静态变量;
可以用来实现Main函数;
11、多态(重点内容)
同一个方法,能实现不同的效果;
静态多态:
静态多态理解为函数的多态;
同一个函数,实现不同的效果 =>函数重载,同一个函数,参数不同,效果不同。
动态多态:
动态多态理解为类的多态;
依靠抽象类和虚方法来实现:abstract和virtual
理解:一个类声明为抽象类(加上abstract),其派生类可以重写其内部的函数;
在抽象类里声明为abstract的函数不能写出函数主体,只能声明,不能定义,不然会报错
派生类不实现重写抽象类的抽象函数会报错
重写抽象函数时无法改变访问修饰符
将抽象函数声明为Virtual可以在不同的派生类里实现不同的方法。
实测感觉直接用abstract也可以实现Virtual的这个功能,不知道Virtual还有没有其他特殊用法
2023.12.6补充:
abstract修饰函数的申明,子类必须去定义基类里申明为abstract的函数,因为去定义这个函数;
virtuai修饰整个函数,子类可以去重写也可以不重写;
override修饰的函数,子类里必须去重写这个函数;
12、接口
关键字:interface
接口的作用就是使得继承自这个接口的类有相似的结构,都会实现接口内的函数这个特性就使得子类都有相似的结构;
13、预处理命令
很实用的是,#region和#endregion组合可以实现自定义代码块的折叠;
#region 注释
代码
#endregion