zoukankan      html  css  js  c++  java
  • 读书笔记—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对象,也不回设置字段和属性
  • 相关阅读:
    批量新增百万条数据 十百万条数据
    sqlserver 组内排序
    EF ++属性会更新实体
    Entity Framework Core: A second operation started on this context before a previous operation completed
    abp Cannot access a disposed object. A common cause of this error is disposing
    abp xunit Can not register IHostingEnvironment. It should be a non-abstract class. If not, it should be registered before.”
    hangfire enqueued but not processing(hangfire 定时任务入队列但不执行)
    EF 更新实体 The instance of entity type 'BabyEvent' cannot be tracked because another instance
    datatable to entiy list 不支持可空类型和枚举类型
    webapi 设置不显示接口到swaggerUI
  • 原文地址:https://www.cnblogs.com/fecktty2013/p/readingnotes-clr-delegate-attr.html
Copyright © 2011-2022 走看看