静态方法
- 特点
- 生命周期一旦创建应用结束才会结束
- 全局
- 效率高(常驻内存)
- 用处
- 用户登录信息
- 系统配置信息
- 系统设置
- SQLHelper
- 缺点
- 静态东西创建多了占用内存会很大,对于使用频率比较高的内容适合,这样可以减少频繁的内存申请
- 调用
- 静态方法调用非静态方法不能直接调用,需要new一下非静态方法所在的类在调用
构造方法
- 用处:初始化对象或数据
- 特点:默认是一个无参构造方法,可以重载
析构方法
- 作用:释放对象,GC垃圾回收器会调用
1 | Close方法关闭对象,没有完全释放 |
虚方法virtual
- 作用:允许子类/派生类进行重写override,实现不一样的功能
- 特点:好维护
抽象方法abstract
- 定义:一定要写在抽象类里面,而且不能new不带方法体
- 与接口的区别:
- 派生类只能继承单个抽象类,派生类可以继承多个接口
- 抽象类里可以定义普通方法、虚方法等,接口只能写规范不能写具体的实现
- 抽象类一般用于不会经常改动的对象(人->男人),接口适用于经常修改,只是一个规范,锲约,定义,功能
1
2
3
4虚方法和抽象方法的区别:
1. 虚方法必须有实现部分,抽象方法没有提供实现部分。抽象方法只定义具体实现需要在派生类中完成。
2. 抽象方法只能在抽象类中声明,虚方法不是。如果类包含抽象方法,那么该类也是抽象的,也必须声明类是抽象的。
3. 抽象方法必须在派生类中重写,这一点和接口类似,虚方法不需要再派生类中重写,对于虚方法派生对象可以重写虚方法里的方法也可以不重写,但是抽象方法的派生对象必须重写抽象类中的抽象方法。
扩展方法ExtendMethod
- 定义:在非泛型静态类中定义的静态方法
- 使用场合:
- 调用密封类中的对象,属性或者方法(扩展密封类)
- 扩展接口
- 在linq链式编程
- 示例
1
2
3
4
5
6
7public static class InvokeCenter{
public static void InvokeManager<T>(this T showClass) where T:new(){
}
}
把密封类作为参数传递进去
泛型
什么是泛型
定义的时候没有指定具体的参数类型,把参数类型的声明推迟到了调用的时候才指定参数类型。解决功能模块相似但处理的数据类型不一样,object带来的装箱拆箱性能损耗,类型参数是在其实例化泛型类型的一个变量时,客户端指定的特定类型的占位符(T)
优点:通用性
泛型约束:关键字where
- new()约束 例子:where T:new() 表示T类型只接受带一个无参数的构造函数。多个约束的情况下new约束必须放到最后
- 结构类型struct/值类型/引用类型约束
- 自定义类型约束
1
2值类型:struct、int、枚举、doubel等
引用类型:数组、接口、委托、类、object、字符串
协变和逆变:针对泛型接口和泛型委托来说的。out代表协变,in代表逆变。协变只能返回结果不能做参数,逆变T只能做参数,不能做返回值
- 使用场景:父类通过子类实例化(逆变in)或者子类通过父类实例化(协变out)的场景
泛型的用处
- 让泛型类、泛型方法、泛型接口、泛型委托更通用
- 约束
- 协变逆变
反射
- exe/dll主要区别是exe文件有入口—metadata(元数据:描述exe/dll文件的数据清单)—-反射可以读取metadata
- 反射:操作matedata的一个类库,可以把它当成一个可以用来读取或者操作元数据的小工具
- 使用场景:MVC/ORM/AOP等
- 反射可以动态读取并且能读取私有对象,通过反射加载dll文件
- 实例
- 加载dll: Assembly.LoadFile(“xxxx.dll”); 或者 Assembly.LoadFrom(“xxxx.dll”);
- 使用反射创建对象
- 加载dll:Assembly asb = Assembly.LoadFile(“xxxx.dll”);
- 获取类型(完整类型名称): Type type = asb.GetType(“类名”);
- 创建类型:
- 不带参数:object obj = Activator.CreateInstance(type)
- 带参数:object obj = Activator.CreateInstance(type, new object[]{对应的参数类型,多个参数用逗号隔开});
- 类型转换:把obj转换为具体的实例类型(as)
- 使用反射创建具有私有构造函数的对象
- Assembly asb = Assembly.LoadFile(“xxxx.dll”);
- Type type = asb.GetType(“类名”);
- object obj = Activator.CreateInstance(type, true);
- 使用反射创建泛型类
- Assembly asb = Assembly.LoadFile(“xxxx.dll”);
- Type type = asb.GetType(“泛型名称并且加上泛型所需参数个数,例如需要三个参数表示为:xxxClass`3”);
- Type makeType = type.MakeGenericType(new Type[] {typeof(int),typeof(string),typeof(bool)})
- object obj = Activator.CreateInstance(makeType)
- 使用反射调用方法
- Assembly asb = Assembly.LoadFile(“xxxx.dll”);
- Type type = asb.GetType(“类名”);
- MethodInfo methodInfo = type.GetMethod(“方法名”);
- methodInfo.Invoke(methodInfo,new object[]{参数});
- dll文件名+类型名称+方法名称类比mvc路由http://localhost:4500/Home/index
- 总结
- 获取dll文件
- 获取到类型名称
- 实例化类型 Activator.CreateInstance
- 找到方法 GetMethod
- 确定方法参数类型 MakeGenericType
- 调用 invoke
泛型实例
1 | public T Find<T>(int id){ |
特性
- 在方法或者类上标注的方法
- 使用场景:数据验证
- 特性的步骤:
- 定义特性
- 标记
- 调用
委托
- 委托是引用类型,保存函数的指针,指向一个函数。调用委托的时候就是在执行被指向的函数。关键字:delegate
多播委托
- 每一个委托都是继承自MulticastDelegate
- 带返回值的多播委托只会返回最后一个方法的值
- 多播委托可以用加减号来操作方法的增加或减少
- 给委托传递相同方法时,生成的委托实例也是相同的(即是同一个委托),如果给委托传递的是匿名方法则对应不同的委托实例
总结
- 泛型:把类型做到通用
- 反射:读取dll文件描述信息(matedata)的一个类库
- 特性:是一个类,继承自Attribute。贴标签,贴上标签就有新的功能,本质就是AOP的另一种实现方式
- 委托:指向方法的指针
事件
- 事件就是委托的安全版本
- 在事件内的外部不能用=号来操作,只能用+=
- 在定义事件类的外部不能调用事件
- 定义事件的关键字是event,只需要在委托前面加上event即是事件
- 示例
1
2
3
4
5delegate void StudentDelegate()
class InvokeDefine{
public event StudentDelegate StudentEvent;
}