C#与设计模式,都是新接触的东西,有很多小的知识点需要理解、记住。下面自己总结一下让印象更深刻!
out和ref
相同的地方:
1. ref和out都是传地址的,所以都会改变实参的值。
2.方法定义和调用方法均必须显式使用 ref/out关键字。
不同的地方:
1. out方法需要必须对形参进行初始化或者赋值,否则编译出错。
2. out传完之后就把形参清空了,所以在进入方法的时候不能使 用形参;而ref可以使用,因为已经初始化过。
3. ref的实参必须初始化,out的实参可初始化可不初始化,反正 进去后都会清掉。
方法重载和方法重写
重载:一个类中的方法名相同,参数的个数,类型不同(多态性)
重写:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。(继承)
堆,栈,堆栈,队列
堆
①堆通常是一个可以被看做一棵树的数组对象。
②堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。
③堆是应用程序在运行的时候请求操作系统分配给自己内存,一般是申请/给予的过程。
④堆是指程序运行时申请的动态内存,而栈只是指一种使用堆的方法(即先进后出)。
栈和堆栈
①栈又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
②栈就像一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来(先进后出)
③栈是操作系统在建立某个进程时或者线程为这个线程建立的存储区域。
队列
①队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
②队列中没有元素时,称为空队列。
③建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针,它指向队头元素;另一个是队尾指针,它指向下一个入队元素的存储位置。
④队列采用的FIFO(先进先出),新元素总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。
装箱和拆箱
装箱在值类型向引用类型转换时发生
拆箱在引用类型向值类型转换时发生
值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用。
值类型有:
byte,short,int,long,float,double,decimal,char,bool struct ,结构体(struct),枚举(enum)
引用类型有:
数组, 类(class), 接口,委托,字符串(string)
值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。引用类型的对象总是在进程堆中分配(动态分配)
相同点:
引用类型可以实现接口,值类型当中的结构体也可以实现接口;
引用类型和值类型都继承自System.Object类。
1.范围方面
值类型包括:结构体(数值类型、bool型、用户定义的结构体),枚举,可空类型。
引用类型包括:数组,用户定义的类、接口、委托,object,字符串(string),用户定义的结构体,可空类型
2.内存分配方面:
数组的元素不管是引用类型还是值类型,都存储在托管堆上。
引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。简称引用类型部署在托管推上。而值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量存储;作为局部变量时,存储在栈上。
3.适用场合:
值类型在内存管理方面具有更好的效率,并且不支持多态,适合用做存储数据的载体;引用类型支持多态,适合用于定义应用程序的行为。
引用类型可以派生出新的类型,而值类型不能,因为所有的值类型都是密封的;
引用类型可以包含null值,值类型不能;
引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。
修饰符和属性
访问修饰符
Public:公有的,是类型和类型成员的访问修饰符。对其访问没有限制。
Internal:内部的,是类型和类型成员的访问修饰符。同一个程序集中的所有类都可以访问
Private:私有的,是一个成员访问修饰符。只有在声明它们的类和结构中才可以访问。
Protected: 受保护的,是一个成员访问修饰符。只能在它的类和它的派生类中访问。
声明修饰符
Partial:在整个同一程序集中定义分部类和结构。
Static: 声明属于类型本身而不是属于特定对象的成员。
Abstract:抽象类,只能是其他类的基类。类中的方法只声明不实现,方法的实现在他的派生类中完成。
Sealed:指定类不能被继承。
Virtual:用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象
Override:提供从基类继承的成员的新实现
New:作修饰符,隐藏从基类成员继承的成员,在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。作运算符,用于创建对象和调用构造函数。
Extern:用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static
属性
属性是一个方法或一对方法。有set(修改,写)和get(访问,读)两种方法。体现了封装性
语法:变量要定义为私有变量
private<返回类型(要与被访问变量的类型相同)> <属性名(与被访问变量同名)>
public <返回类型(要与被访问变量的类型相同)> <属性名(不能与被访问变量同名)> /将属性名第一个字母大写
{
get{ return <被访问变量>;}
set{ <被访问变量> = value;}
}
类和实例
类是具有相同属性和功能的对象集合。(class关键字)
class Cat
{
}
实例是一个真实的对象。(new关键字)
Cat cat;//声明一个cat对象
cat=new cat();//将cat对象实例化
这两个可以合在一起写成:
Cat cat=new cat();//cat()是构造方法(也叫构造函数),是对类进行初始化,与类同名但没有返回值,在new的时候调用。
关键字
virtual
在使用方法重写的时候,为了让子类可以完全的重写父类中的成员,父类在定义这些成员的时候,一定要使用virtual关键字,让可以重写的方法成为虚方法,让可以重写的属性成为虚属性。
override
子类在重写这个方法或属性的时候,将virtual替换成override关键字,代表已将父类的成员替换为了它自己的成员并实现。
base
如果想在子类的方法中再用父类的那个被覆盖的方法时,只需要使用base关键字就可以代表继承的父类了
void
void关键字在c#中代表没有类型。如果作为函数的返回值类型,即代表函数没有返回值。如果用来定义指针,代表定义了一个无类型指针。
interface
用来声明一个接口,接口名前要加大写字母I,接口的方法或属性前面不能有修饰符,方法没有方法体