第十天
复习:
委托是类型
并且还是引用类型
使用委托的时候必须new一个委托对象, 即便看到的代码没有new委托对象, 编译器也会在编译时帮我们加上new, 赋值给委托的方法, 其实是存储在委托对象中的;
委托的使用步骤:
1.定义一个委托类型: pubic delegate void WeiTuoDelegate();
2.声明一个委托变量: WeiTuoDelgate wd =new WeiTuoDelgate (方法名);
3.调用委托: 先判断委托 是否为null wd. Invoke();
什么情况下用委托? 委托的作用?
当一个类型中需要潜入一段代码, 但是这段代码具有不确定性是根据使用者个类型的用户来确定代码的, 这种情况下就可以使用该类型中, 使用一个委托, 保证在某种情况下回调用该委托, 这时, 用户将对应的方法传递给该委托, 则就会带哦用这个方法;
定义控件中的事件会大量使用到委托 (写事件的时候会用到委托)
可以把静态方法或者私有方法赋值给委托变量, 赋值后, 只要能使用到该委托变量的敌法高就能使用该方法, 打破了访问修饰符的限制 ;
多播委托 (委托链, 委托的组合)
方法调用的顺序与增加方法时的顺序是一致的, 但是,不要依赖于这个顺序 ;
结果是最后一个的值, 前面的值都会被覆盖掉
多播委托内部是将绑定在当期委托对象上的每个方法, 都转换为一个委托对象, 并且存储在了以个叫 invocatinonList的object数组中, 然后当调用委托的时候,其实就是循环遍历 invocationList数组, 并且调用其中的每一个委托 ;
循环调用每个方法中的值 同时接收每一个返回值
多播委托中, 如果其中有个方法发生异常, 则后续的方法不再执行;
如果委托时,如果不是用+=而是直接使用=, 赋值,会将前面绑定的所有其他方法(委托)都覆盖
也是只能存储同一类型的数据; 委托的本质就是一个类把方法包装了一下 委托都继承自System. MulticastDelegate, 而它又继承自System. Delegate 多播委托就是有一个委托数组, 一次调用;
委托的不可变性
1. 委托具有类似于string一样的不可变性;
2. 建议使用的时候尽量少定义自己的委托, 使用系统中已经有的委托;减少程序集中定义的类型的数量
事件语法:
Event ProcessWordDelegate
加了event关键字实现事件机制的好处: 用了event事件, 不可以修改事件已经注册的值;
通过委托来实现事件的功能的问题:
1.可以在类的外部来触发, 因为委托变量 的访问修饰符的public的, 所以在外部任何地方都能触发. 如果将访问修饰符改成private ,那么在调用时, 就不能触发了, 也不能赋值;
2.由于委托可以使用=赋值, 所以, 就有可能将前面的所有的已经注册的事件, 处理程序 都覆盖;
3.因为事件只能通过+=或者-=来赋值 ,所以避免了使用=赋值时的覆盖问题;
4.使用事件与使用委托的区别就是一个event关键字
5.其实事件最终是生成了: 1.一个私有的委托; 2.两个public的方法Add和Remove 分别实现事件;
事件与委托的区别:
委托和事件没有可比性,因为委托是类型,事件是对象(可以理解为对委托变量的封装。d),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。(举例子:三种实现事件方式的区别)
因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。add、remove。
事件是用来阉割委托实例的。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。
程序集
程序集是.NET中的概念;
.NET中的dll .和exe文件都是程序集;
程序集(Assembly), 可以看做是一堆相关类打一个包, 相当于java中的jar包(*);
程序集包含: 类型元数据 (描述在代码中定义的每一类型和成员, 二进制形式),程序集元数据(程序集清单,版本号,名称等), IL代码(这些都被装在exe或dll中,), 资源文件; 每个程序集都有自己的名称, 版本等信息; 这些信息可以通过AssemblvInfo. Cs文件来自己定义;
使用程序集的好处?
程序中只引用必须的程序集, 减小程序的尺寸;
程序集可以封装一些到吗,只提供必要的访问接口;
如何添加程序集的引用?
添加路径, 项目引用, GAC (全局程序集缓存)
不能循环添加引用;
在c#中添加其他语言的dll文件的引用; (参考P/Invoke,在.net中调用非程序集的dll)extern
反射
反射无处不在, Vs的智能提示, 就是通过反射获取到类的属性,
就是动态获取程序集中的元数据来操作类型的
Type是对类的描述,反射就是直接通过.dll来创建对象,调用成员.
通过类型元数据来获取对象的一些相关信息,并且还可以实例化对象调用方法等,这个就叫做“反射”。
编译器的智能提示就是反射的一个应用。
反射:简单的理解就是通过类型元数据创建对象、调用对象的成员等
加载程序集:
Assembly . LoadFile (地址);
获取其中的类或方法
方法:
Type类的方法:
IsAssignableFrom
IsSubclassof 验证是否是一个的子类
接口与类之间, 只存在实现, 没有父子关系;
接口, 抽象类, 静态类都不能被实例化, 都认为是抽象类;