读书笔记—CLR via C#委托和attribute

前言

这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享

委托

  • 类型安全的回调函数,函数签名定义声明、指向静态或实例方法
  • 派生自System.MulticastDelegate的类
  • 将方法绑定到委托时,C#和CLR都允许引用类型的协变性和逆变性
    • 协变性指方法能返回从委托的返回类型派生的类型
    • 逆变性是指方法的参数可以是委托参数类型的基类
    • 如: delegate object Callback(FileStream fs) 和 string Method(Stream s)兼容
    • 注意:协变性和逆变性只能用于引用类型,不能用于值类型或void
    • 值类型和void不可变,因为存储结构是变化的,而引用类型的存储结构始终是一个指针。编译器会检查报错
    • 如: 以上委托和 int OtherMethod(Stream s)不兼容
  • 当使用实例方法包装委托时,对象的地址作为隐式的this参数传给实例方法
  • 包装实例方法可以维护一些状态,在回调方法中利用状态信息
  • 委托重写了运算符==、GetHashCode和Equals,如果不同的委托使用相等的类型指向相同的方法,那么就是相同的
  • 委托是不可变的,某一些特征可以和string或者匿名对象相同
  • 委托的合并,实际上是重现创建一个对象,然后使用TargetList包含原来所有委托的引用列表
  • 委托的执行
    • 对委托的执行先判断是否为委托链,委托链执行Invoke会遍历所有包装委托方法并执行
    • 委托链的签名如果有返回值,那么执行完成只返回最后一个委托的结果,其他值会被丢弃
    • 同步顺序调用链中的委托,中间出现问题,后续对象都调用不了,不够健壮(鲁棒)robustness
  • C#的简化语法
    1. 不需要构造委托对象
    2. 不需要定义方法, 可以定义匿名方法或者lambda表达
    3. 匿名私有方法,其实是在当前对象上定义并缓存,并使用[CompilerGenerated]特性
    4. 如果不包含对实例成员的引用,编译器会生成一个静态的匿名函数,因为它的效率比实例方法更高,因为不需要额外的this参数
    5. 但是如果匿名函数的代码确实引用了一个实例成员,编译器会生成一个非静态匿名函数
    6. 委托参数可以包含ref或out,必须显式指定,不可以让编译器推断
    7. 当lambda表达式造成编译器生成一个类,而且参数/局部变量被转变成该类的字段后,变量引用的对象的生存期被延长了
  • DynamicInvoke允许调用委托对象的回调方法,传递一组在运行时确定的参数。如果参数不兼容则抛异常

特性(Attribute)

  • AttributeUsageAttribute属性
    • Target... Inhirit 可继承(针对类、方法、属性、事件、字段、方法、方法返回值、参数)
    • AllowMultiple 将属性应用于同一个元素多次
  • 逻辑上,当编译器检测到向一个目标元素应用了一个定制attribute时,编译器会调用attribute类的构造器,向他传递任何指定的参数,从而构造attribute类的一个实例。然后,编译器会采用增强型构造器语法所指定的值,对任何公共字段和属性进行初始化
  • 在构造并初始化好定制attribute类的对象之后,编译器会将这个attribute对象的状态序列化到目标元素的元数据记录项中
  • 所谓定制attribute,就是一个类的实例,它被序列化成驻留在元数据中的一个字节流。运行时,反序列化构造实例
  • 关键静态方法 IsDefined, GetCustomAttributes, GetCustomAttribute,会搜索指定attribute类或者它的派生类的应用
  • IsDefined不会构造一个attribute对象,也不回设置字段和属性
时间: 2024-11-20 07:21:21

读书笔记—CLR via C#委托和attribute的相关文章

读书笔记—CLR via C#反射

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 程序集加载 AppDomain.Load 尽量避免使用此方法加载程序集,因为Assembly不是从System.MarshalByRefObject派生,所以程序集对象必须按值封送回发出调用的那个AppDomain,但是CLR会使用发出调用的那

读书笔记—CLR via C#章节11-13

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 事件 事件的本质 初始化为null的私有委托字段 封装add_Event和remove_Event方法 add_Event和remove_Event的可访问性同Event字段的可访问性,包括virtual和static修饰 事件的编码建议 使用

读书笔记—CLR via C#线程25-26章节

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 线程 线程内部组成 线程内核对象 thread kernel object,在该结构中,包含一组对线程进行描述的属性.数据结构中还包括所谓的线程上下文thread context.上下文是一个内存块,包含了CPU的寄存器集合,占用几百到几千个字

读书笔记—CLR via C#章节3

这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享. 强命名程序集 优点 程序集共享 版本共存,解决DLL hell 安全策略(防篡改) 发布策略控制 标识组成 文件名(不计扩展名)+版本号+语言文化+公钥 CLR加载方式 弱命名程序集私有部署,CLR在基目录或子目录中搜索时只使用程序集名称 CLR搜

读书笔记—CLR via C#线程27章节

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 同步IO执行过程,拿Read举例 托管代码转变为本地用户模式代码,Read在内部调用Win32的ReadFile函数 ReadFile分配IRP(IO Request Packet) IRP包括:一个文件句柄.文件偏移量.Byte[]数组 IO

读书笔记—CLR via C#同步构造28-29章节

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 类库和线程安全 在类设计中,类和方法的线程安全的设计尽量和FCL保持一致 保证所有的静态方法都是线程安全的 不保证实例方法是线程安全的 基元用户模式和基元内核模式构造 用户模式构造 易失构造(volatile construct),它包含一个简

读书笔记—CLR via C#章节1-2

这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享. 程序集 描述:一个或多个类型定义文件及资源文件的集合 特征:可重用.可保护.可版本控制的单元 生成:可通过C#编译器(或其他编译器)或AL.exe生成 组成: 托管模块(module) PE头,PE32或PE32+,面向CPU架构的信息 CLR头,

读书笔记—CLR via C#章节8-10

前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享 构造函数 抽象类默认的构造函数可访问为protected,普通类默认为public 派生类默认调用一个基类构造器(如果没有无参构造器,则需要显式调用) 不通过构造函数创建对象? 静态方法Object.MemberwiseClone,分配内存复制

《C#本质论》读书笔记(12)委托和Lambda表达式

12.1. 委托概述 12.1.2 委托的数据类型 为了减少重复代码数量,可以将比较方法作为参数传递给 BubbleSort()方法.此外,为了将方法作为参数传递,必须有一个能够标识方法的数据类型--也就是委托.这里的委托类型是 ComparisonHandler .  c# 2.0之前的写法 class DelegateSample { static void Main(string[] args) { //int[] arr = { 10, 20, 30, 40, 50 }; int[] a