栈 | 堆 |
---|---|
由编译器自动分配、释放,函数体中的变量通常在栈上 | 由程序员分配、释放,用 new、malloc 等分配内存的函数就是在堆上 |
栈中的数据是由顺序的,是一片连续的内存区域,保持先进后出的原则 | 堆中的数据是无顺的,不是连续的内存区域 |
栈内存不需要人工干预,也不需要 GC 管理,栈顶元素使用完毕就会马上释放 | 堆内存需要人工干预释放,但是也可以不释放,等待内存到达一定峰值的时候由 GC 来回收 |
所谓的委托本质上就是一个类,它是将方法作为参数传入到另一个方法中。例如 onclick 事件中的参数就是一个方法。
静态构造函数是最先被执行的构造函数,一个类中允许有且只有一个无参静态构造函数。
静态变量–>静态构造函数–>实例变量–>实力构造函数
CTS | CLS | CLR |
---|---|---|
通用类型系统 | 通用语言规范 | 公共语言运行库 |
.NET中每种语言都有自己的类型,通过 CTS 提供的公共类型翻译成对应的 .NET 类型 | 每种语言都有自己的语法,通过 CLS 提供的公共语法,翻译成对应的 .NET 语法 | 相当于汽车发动机,负责执行 IL |
值类型直接存储数据,当值类型变量声明后不管是否已经赋值都会为其分配内存空间。引用类型持有数据的地址引用,当声明一个引用类型的时候只在栈中分配了用于容纳数据存储地址的空间,并没有为其在堆上分配存储数据的空间,只有创建引用类型实例的时候才会在对上分配数据存储空间,并将这个空间地址保存到栈上分配的数据存储地址中。一般来说操作引用类型就是对指针进行操作,并非对引用类型本身进行操作,但是值类型则是对其本身进行操作。
类 class 是分配在内存对上的引用类型,可以被实例化,可以实现接口和继承其他类,还能作为基类型。结构 struct 是分配在内存栈的值类型,不能作为基类型使用,但可以实现接口。
作为运算符:创建对象实例; 作为修饰符:在派生类中定义一个与基类重名的方法,隐藏掉基类方法; 作为约束:泛型约束定义,约束可使用的泛型类型。
int? 为可空类型,默认值为 null,int 默认值为 0 。int? 是通过 int 装箱为引用类型实现的。
值传递:系统为被调用方法的形参分配内存空间,并将实参的值按照位置一一对应赋值给形参,此后被调用方法中形参值的改变都不会影响到实参。 引用传递:系统将实参的引用地址(即实参数据的存储内存地址)传递给形参,因此形参与实参引用的是同一个内存地址,这样在被调用方法中形参值得改变都会影响到实参。 简单说就是按值传递传递形参会复制实参的值数据,也就是说会在栈上多创建一个相同的变量,按引用传递是形参复制实参数据内存地址。
ref 既可以把值传递到方法中,也可以传递到方法外,out 只能把值传递到方法外。