CLR via c#读书笔记九:接口
1、接口对一组方法签名进行了统一命名。接口还能定义事件、无参属性和有参属性(C#的索引器)。
2、c#禁止接口定义任何一种静态成员。
3、C#编译器要求将实现接口的方法标记为public。CLR要求将接口的方法标记为virtual。不将方法显示标记为virtual,编译器会将它们标记为virtual和sealed;这会阻止派生类重写接口方法。将方法显式标记为virtual,编译器就会将方法标记为virtual,使派生类能重写它。派生类不能重写sealed的接口方法。但派生类可重新继承同一个接口,变为接口方法提供自己的实现:
//这个类派生自Object,它实现了IDisposable
internal class Derived:Base,IDisposable{
//这个方法不能重写Base的Dispose,
//'new'表明该方法重新实现了IDisposable的Dispose方法
new public void Dispose(){
Console.WriteLine("Derived`s Dispose");
//注意,下面这行代码展示了如何调用基类的实现(如果需要的话)
//base.Dispose();
}
}
4、隐式和显示接口方法实现
类型加载到CLR中时,会为该类型创建并初始化一个方法表。在这个方法表中,类型引入的每个新方法都有对应的记录项;另外,还为该类型继承的所有虚方法添加了记录项。继承的虚方法既有继承层次结构中的各个基类型定义的,也有接口类型定义的。
internal sealed class SimpleType:IDisplsable{
public void Dispose(){
Console.WriteLine("Dispose");
}
}
类型的方法表将包含以下方法的记录项。
- Object(隐式继承的基类)定义的所有虚实例方法。
- IDisposable(继承的接口)定义的所有接口方法。本例只有一个方法,即Dispose,因为IDisposable接口只定义了这个方法。
- SimpleType引入的新方法Dispose。
为了简化编程,C#编译器假定SimpleType引入的Dispose方法是对IDisposable的Dispose方法的实现。之所以这样假定,是由于Dispose方法的可访问性public,而接口方法的签名和新引入的方法完全一致。也就是说,两个方法具有相同的参数和返回类型。如果新的Dispose方法被标记为virtual,C#编译器仍然认为方法匹配接口方法。C#编译器将新方法和接口方法匹配起来之后,会生成元数据,指明SimpleType类型的方法表中的两个记录项应引用同一个实现。
现在重新SimpleType,以便于看出区别:
internal sealed class SimpleType:IDisposable{
public void Dispose(){ Console.WriteLine("public Dispose"); }
void IDisposable.Dispose(){ Console.WriteLine("IDisposable Dispose"); }
}
在C#中,将定义方法的那个接口的名称方法名前缀(例如IDisposable.Dispose),就会创建显示接口方法实现(EIMI)。注意,C#中不允许在定义显示接口方法时指定可访问性(比如public或private)。
5、泛型和接口约束
泛型类型参数约束的好处。
第一个好处在于,可将泛型类型参数约束为多个接口。这样一来,传递的参数的类型必须实现全部接口约束。
//M的类型参数T被约束为只支持同时实现了
//IComparable和IConvertitle接口的类型
private static Int32 M<T>(T t)where T:IComparable,IConvertible{
...
}
接口约束的第二个好处是传递值类型的实例时减少装箱。
C#编译器为接口约束生成特殊IL指令,导致直接在值类型上调用接口方法而不是装箱。不用接口约束便没有其他办法让C#编译器生成这些IL指令,如此一来,在值类型上调用接口方法总是发生装箱。一个例外是如果值类型实现了一个接口方法,在值类型的实例上调用这个方法不会造成值类型的实例装箱。
6、设计:基类还是接口
- IS-A对比CAN-DO关系
类型只能继承一个实现。如果派生类型和基类型建立不起IS-A关系,就不用基类而用接口。接口意味着CAN-DO关系。如果多种对象类型都“能”做某事,就为它们创建接口。例如,一个类型能将自己的实例转换为另一个类型(IConvertible),一个类型能序列化自己的实例(ISerializable)。注意,值类型必须从System.ValueType派生,所以不能从一个任意的基类派生。这时必须使用CAN-DO关系并定义接口。
- 易用性
基类派生比接口容易得多。 - 一致性实现
- 版本控制
CLR via c#读书笔记九:接口的更多相关文章
- CLR via c#读书笔记九:字符、字符串和文本处理
1.在.NET Framework中,字符总是表示成16位unicode代码值(关于unicode.utf8等可以到http://www.ruanyifeng.com/blog/2007/10/asc ...
- [Clr via C#读书笔记]Cp13接口
Cp13接口 类和接口继承 接口只提供签名,不提供实现:等效于契约:凡事能使用具名接口的地方都能够使用实现了的接口. 定义接口 定义很简单,FCL也提供了大量的现成接口供使用: 继承接口 类不能多继承 ...
- CLR via C# 读书笔记-21.托管堆和垃圾回收
前言 近段时间工作需要用到了这块知识,遂加急补了一下基础,CLR中这一章节反复看了好多遍,得知一二,便记录下来,给自己做一个学习记录,也希望不对地方能够得到补充指点. 1,.托管代码和非托管代码的区别 ...
- Clr Via C#读书笔记---I/O限制的异步操作
widows如何执行I/O操作 构造调用一个FileStream对象打开一个磁盘文件-----FileStream.Read方法从文件中读取数据(此时线程从托管代码转为本地/用户模式代码)- ...
- Clr Via C#读书笔记---计算限制的异步操作
线程池基础 1,线程的创建和销毁是一个昂贵的操作,线程调度以及上下文切换耗费时间和内存资源. 2,线程池是一个线程集合,供应你的用程序使用. 3,每个CLR有一个自己的线程池,线程池由CLR控制的所有 ...
- Clr Via C#读书笔记---CLR寄宿和应用程序域
#1 CLR寄宿: 开发CLR时,Microsoft实际是将他实现成包含在一个dll中的COM服务器.Microsoft为CLR定义了一个标准的COM接口,并为该接口和COM服务器分配了GUID.安装 ...
- Clr Via C#读书笔记---程序集的加载和反射
#1 加载程序集 Assembly.Load: public class Assembly { public static Assembly Load(AssemblyName assemblyRef ...
- 读书笔记 C# 接口之浅析
一.接口可以包含 属性.方法.事件和索引器: 二.接口不能被实例化: 三.一个类可以继承多个接口: 四.接口不能包含方法的实现: 五.继承接口的类必须实现接口中所有成员: 六.显式实现接口的成员,不能 ...
- CLR via C# 读书笔记-26.线程基础
前言 这俩个月没怎么写文章做记录分享,一直在忙项目上线的事情,但是学习这件事情,停下来就感觉难受,clr线程这章也是反复看了好多遍,书读百遍其义自见,今天我们来聊下线程基础 1.进程是什么,以及线程起 ...
随机推荐
- Java---页面之间传值跳转
从首页A进入页面B,然后从B页面登录,成功后跳转到A页面,并打印一句话“登录成功”,传值需要用的后台的. 在B页面写: <% session.setAttribute("key ...
- UVa 580 - Critical Mass(递推)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- SpringMVC使用校验validator校验对象属性
1.pom.xm添加依赖 <dependency> <groupId>javax.validation</groupId> <artifactId>va ...
- win8安装wampserver报403错误解决方法
看着别人开始体验win8了,前几天我也安装了win8系统,总体来说还不错,但是今天安装完Wampserver后,浏览器输入localhost,竟然报了403错误,我以为我安装出错了,后来研究了半天,发 ...
- CMarkup成员方法简介 (转)
CMarkup成员方法简介 (转) 转自:http://blog.csdn.net/magictong/article/details/6669837翻译:magictong(童磊)2011年7月版权 ...
- 【Node.js学习笔记】使用Gulp项目自动化构建工具
刚接触node.js,对前端的一些东西还不是很清楚,据说Gulp这东西很强大,先来看看从网上抄的一段关于自动化构建的描述: 在为数众多的中小型软件作坊中,不存在自动化构建和发布工具.构建.交付准备环境 ...
- 【Linux学习笔记】Linux-CentOS下安装Redis
虚机装了个Linux,尝试安装了一下Redis这款NoSQL数据库玩玩,作为Linux小白,我安装的是有可视化桌面的CentOS,所以不是纯命令行操作,怎么方便怎么来嘛~ 1.官网下载Redis到指定 ...
- Keil开发的ARM程序main函数之前的汇编分析
Keil开发的ARM程序main函数之前的汇编分析 ——BIN文件中RW段的数据移动 系统平台: STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储; FLASH地址范围 ...
- Java中,如何跳出当前的多重嵌套循环
在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环.(Java中支持带标签的break和continue语句)
- CSS-自定义变量
使用背景: 一些常见的例子: 为风格统一而使用颜色变量 一致的组件属性(布局,定位等) 避免代码冗余 *更方便的从CSS向JS传递数据(例如媒体断点) 为什么使用: 以下几点是未来CSS属性的简短说明 ...