读书笔记—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#的简化语法
- 不需要构造委托对象
- 不需要定义方法, 可以定义匿名方法或者lambda表达
- 匿名私有方法,其实是在当前对象上定义并缓存,并使用[CompilerGenerated]特性
- 如果不包含对实例成员的引用,编译器会生成一个静态的匿名函数,因为它的效率比实例方法更高,因为不需要额外的this参数
- 但是如果匿名函数的代码确实引用了一个实例成员,编译器会生成一个非静态匿名函数
- 委托参数可以包含ref或out,必须显式指定,不可以让编译器推断
- 当lambda表达式造成编译器生成一个类,而且参数/局部变量被转变成该类的字段后,变量引用的对象的生存期被延长了
- DynamicInvoke允许调用委托对象的回调方法,传递一组在运行时确定的参数。如果参数不兼容则抛异常
特性(Attribute)
- AttributeUsageAttribute属性
- Target... Inhirit 可继承(针对类、方法、属性、事件、字段、方法、方法返回值、参数)
- AllowMultiple 将属性应用于同一个元素多次
- 逻辑上,当编译器检测到向一个目标元素应用了一个定制attribute时,编译器会调用attribute类的构造器,向他传递任何指定的参数,从而构造attribute类的一个实例。然后,编译器会采用增强型构造器语法所指定的值,对任何公共字段和属性进行初始化
- 在构造并初始化好定制attribute类的对象之后,编译器会将这个attribute对象的状态序列化到目标元素的元数据记录项中
- 所谓定制attribute,就是一个类的实例,它被序列化成驻留在元数据中的一个字节流。运行时,反序列化构造实例
- 关键静态方法 IsDefined, GetCustomAttributes, GetCustomAttribute,会搜索指定attribute类或者它的派生类的应用
- IsDefined不会构造一个attribute对象,也不回设置字段和属性
读书笔记—CLR via C#委托和attribute的更多相关文章
- 读书笔记—CLR via C#反射
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节11-13
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节3
这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深 ...
- 读书笔记—CLR via C#线程27章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#线程25-26章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#字符串及文本
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 《C#本质论》读书笔记(12)委托和Lambda表达式
12.1.委托概述 12.1.2 委托的数据类型 为了减少重复代码数量,可以将比较方法作为参数传递给 BubbleSort()方法.此外,为了将方法作为参数传递,必须有一个能够标识方法的数据类型--也 ...
- 读书笔记—CLR via C#异常和状态管理
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节8-10
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
随机推荐
- 库函数atoi()的实现
int atoi(const char *nptr); 假设第一个非空格字符存在,是数字或者正负号则開始做类型转换,之后检測到非数字(包含结束符 \0) 字符时停止转换.返回整形数. 否则,返回零. ...
- ThreadLocal的内存泄露(转)
ThreadLocal的目的就是为每一个使用ThreadLocal的线程都提供一个值,让该值和使用它的线程绑定,当然每一个线程都可以独立地改变它绑定的值.如果需要隔离多个线程之间的共享冲突,可以使用T ...
- Ubuntu中全然卸载Nginx
Nginx尽管好用,可是一旦关键配置文件被改动,想要卸载重装却是相当困难.本人由于採用apt-get方式安装后又源代码安装了Nginx,结果出现冲突,卸载不了,安装不上,非常是蛋疼.基本的问题还是Ng ...
- Centos7系统配置上的变化(二)网络管理基础
原文 Centos7系统配置上的变化(二)网络管理基础 上篇简单介绍了CentOS 7 在服务和网络方面的一点变化,先前很多烂熟于心的操作指令已经不适用了,不管是否习惯,总要接受.熟悉这些变化. 写上 ...
- js日期操作
1.最基本的日期操作 var mydate = new Date(); set/get FullYear,Month,Date,Hour,Minutes,Second可以随意拼接 toLocale ...
- hdu 1700 Points on Cycle 水几何
已知圆心(0,0)圆周上的一点,求圆周上另外两点使得三点构成等边三角形. 懒得推公式,直接用模板2圆(r1=dist,r2=sqrt(3)*dist)相交水过 #include<cstdio&g ...
- javascript 中的location.pathname
1 location.pathname; 这在之前我没怎么注意过,所以研究研究.location.pathname:返回URL的域名(域名IP)后的部分.例如 http://www.joymood.c ...
- 【百度地图API】建立全国银行位置查询系统(二)——怎样为地图添加控件
原文:[百度地图API]建立全国银行位置查询系统(二)--怎样为地图添加控件 <摘要>你将在第二章中学会以下知识: 使用手写代码的利器——notepad++: 如何为地图添加控件——鱼骨. ...
- 在Windows系统中安装集成的PHP开发环境
原文:在Windows系统中安装集成的PHP开发环境 刚想学php的,又不会配置复杂php的环境,可以使用集成的,目前网上提供常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XA ...
- python tcp socket 多线程
不多说,直接上代码 client.py #!/usr/bin/python import socket,sys,string host="localhost" port=8000 ...