前言

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

事件

  • 事件的本质
    • 初始化为null的私有委托字段
    • 封装add_Event和remove_Event方法
  • add_Event和remove_Event的可访问性同Event字段的可访问性,包括virtual和static修饰
  • 事件的编码建议
    • 使用virtual void OnXXX来定义事件的调用
    • 如果对象向事件注册一个方法,对象便不可垃圾回收。所以最好在dispose中注销事件
  • 事件调用的优化过程
    • if(Event!=null) Event(this,e);  事件变量的线程竞态问题
    • 复制到临时变量, EventHandler<EventArgs> temp = Event; if(temp!=null) temp(this, e)
    • 以上代码可能会被内联代码优化掉,所以保险一点,考虑下一条
    • EventHandler<EventArgs> temp = Interlocked.CompareExchange(ref Event, null, null); if(temp!=null) temp(this, e);
  • 试图删除一个从未添加过的方法,Delegate的Remove方法内部不做任何事情
  • add和remove方法用线程安全的一个已知的模式更新一个值
  • 手动实现事件包装器的关键在于,使用容器存储键和委托列表 Dictionary<EventKey, Delegate> m_events
  • EventHandler<T>在老版本中T约束为EventArgs,新版本去除了此种约束
  • 允许显式定义事件 EventHandler<T> Handler { add { events += value; } remove{ events -= value;} }
  • 事件默认同步执行委托列表,并且任何一个委托出现异常会终止执行

泛型

  • 开放类型定义的静态构造函数和静态字段,在封闭类型之间不会共享
  • 为了缓解代码爆炸,CLR提供了优化
    • 编译器为引用类型的泛型的编译代码时可以共享的
    • 值类型则不可以,每个值类型对应一份不同的JIT编译代码
  • 泛型接口可以缓解装箱操作,并且不会丧失类型的安全性。如IEquable泛型接口
  • 泛型约束struct不兼容可空类型Nullable

协变和逆变

  • 协变和逆变泛型类型参数在分配和使用泛型类型方面提供了更大的灵活性
  • 利用协变类型参数,可以执行非常类似于普通的多态性的分配
  • 通常,协变类型参数可用作委托的返回类型,而逆变类型参数可用作参数类型
  • 对于接口,协变类型参数可用作接口的方法的返回类型,而逆变类型参数可用作接口的方法的参数
  • 泛型接口或泛型委托类型可以同时具有协变和逆变类型参数
  • 变体不适用于委托组合
  • Func 泛型委托(如 Func<T, TResult>)具有协变返回类型和逆变参数类型。 Action 泛型委托(如 Action<T1, T2>)具有逆变参数类型
  • 实际上数组(只支持object[] = string[] 不支持 object[] = int[]. 值类型数组没有协变)和委托方法签名,已经具备协变和逆变
  • 只有在编译器能验证类型之间存在一个引用转换的前提下,才能应用这些可变性
  • 由于需要装箱,值类型不具备这种可变性。泛型类型针对值类型不具备可变性
  • 对于实参使用out或ref关键字的方法,不允许可变性

接口

  • 实现接口的方法必须是公共的
  • CLR默认将该方法生成为virtual和sealed,如果显式指定virtual,可以为非密封
  • 在一个对象上调用一个接口方法(使用对象类型调用),将调用该方法在该对象的类型中的实现
  • 将值类型转型为接口类型,会发生装箱
  • 显式接口实现不允许指定可访问性,自动设为private,调用接口方法必须通过接口类型变量来进行
  • EIMI方法不能标记为virtual,所以不能被重写,因为EIMI方法并非真的是类型对象模型的一部分
  • 对于接口泛型约束,C#编译器会生成特定的IL指令,这些指令导致直接在值类型上调用接口方法,不对其进行装箱
  • 如果不适用接口约束,就没有其他方法让编译器生成这些IL指令,如此一来,在值类型上调用接口方法总是会造成装箱
  • 如果继承多个接口,而接口又有相同名称和签名的方法,必须使用显式接口方法实现
  • EIMI只能通过接口调用,并且不能由派生类调用。EIMI应该慎用

读书笔记—CLR via C#章节11-13的更多相关文章

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

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

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

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  3. 读书笔记—CLR via C#章节4-7

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

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

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

  5. 《C#从现象到本质》读书笔记(九)第11章C#的数据结构

    <C#从现象到本质>读书笔记(九)第11章C#的数据结构 C#中的数据结构可以分为两类:非泛型数据结构和泛型数据结构. 通常迭代器接口需要实现的方法有:1)hasNext,是否还有下一个元 ...

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

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

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

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

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

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  9. 读书笔记—CLR via C#异常和状态管理

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

随机推荐

  1. PKU 1509 Glass Beads (最小表示法)

    题意:有一个环形字符串,让你找一个位置切一刀使得字符串字母序最小.输出这个位置. 思路:能够看成两个字符串比較.一个是从下标0開始(0~n-1),一个从下标1開始(1~n-1,0). 然后两个指针i= ...

  2. SQL Mirroring[Hot back up with Double machine]

    Background: It's fairly common for businesses to want to provide some high availability for their SQ ...

  3. 2014年辛星全然解读html第八节

    经过前面七节的学习,我感觉大家的HTML的功底也差点儿相同了,并且我特别的删去了某些东西,比方框架,假设回到几年前,那么框架是很流行的,可是如今都到了2014年了,这些东西早就该被遗忘了,因此,我果断 ...

  4. JAVA学习第六十二课 — TCP协议练习

    通过练习掌握TCP在进行传输过程中的问题 练习1:创建一个英文大写转换server client输入字母数据,发送给服务端,服务端收到后显示到控制台,并将该数据转成大写返回client,知道clien ...

  5. Android 源码编译

    Google官方资料参考 http://source.android.com/source/building-running.html 1. 环境设置, 下载好源码后,进入源码目录,即之前执行 rep ...

  6. 笔试题&amp;面试题:设计一个复杂度为n的算法找到单向链表倒数第m个元素

    设计一个复杂度为n的算法找到单向链表倒数第m个元素.最后一个元素假定是倒数第0个. 提示:双指针查找 相对于双向链表来说,单向链表仅仅能从头到尾依次訪问链表的各个节点,所以假设要找链表的倒数第m个元素 ...

  7. Java变量参数

    Java1.5添加新功能:可变参数:它适用于参数不确定性的数量,判断形势的类型.java变量参数数组操作. 特点: 1.今天的参数列表只能持续. 2.省略号(...)位于变量类型和变量名之间,前后有无 ...

  8. Tyvj P1015 公路骑 (DP)

     叙述性说明 Description 一个特殊的单行道都在每公里公交车站.们乘坐汽车的公里使来付费. 比如例子的第一行就是一个费用的单子. 没有一辆车子行驶超过10公里.一个顾客打算行驶n公里(1 ...

  9. Swift # 项目框架

    利用Swift--简单的项目界面流程. TabBar+Navigation底部导航控制,界面的切换. GitHub源码分享,地址: URL:https://github.com/SpongeBob-G ...

  10. 饼干怪兽和APT攻击

    APT攻击就像一个孩子,你通过各种方式窃取他们的大脑要拿出饼干,为了防止恶意攻击,过失作为母亲未能发现和防止饼干盗窃贼如.于她仅仅监视厨房椅子.衣柜门或烤箱门的开启.建立起有效防御目标攻击与APT攻击 ...