建议43:让接口中的泛型参数支持协变

除了上一建议中提到的使用泛型参数兼容接口不可变性外,还有一种办法是为接口中的泛型声明加上out关键字来支持协变,如下所示:

    interface ISalary<out T>    //使用out关键字
{
void Pay();
}
        static void Main(string[] args)
{
ISalary<Programmer> s = new BaseSalaryCounter<Programmer>();
ISalary<Manager> t = new BaseSalaryCounter<Manager>();
PrintSalary(s);
PrintSalary(t);
} static void PrintSalary(ISalary<Employee> s) //用法正确
{
s.Pay();
}

这段代码在FCL4.0以前是不能编译通过的,因为IEnumerable<T>这个接口在FCL中没有被声明为IEnumerable<out T>:

        static void Main()
{
IList<Programmer> programmers = new List<Programmer>();
IList<Manager> managers = new List<Manager>();
PrintPersonName(programmers);
PrintPersonName(managers);
} static void PrintPersonName(IEnumerable<Employee> persons)
{
foreach (Employee person in persons)
{
Console.WriteLine(person.Name);
}
}

FCL4.0对很多接口进行了修改以支持协变,如IEnumerable<out T>、IEnumerator<out T>、IQuerable<out T>等。由于IEnumerable<out T>现在支持协变,所以上段代码在FCL4.0中能运行得很好。

在我们自己的代码中,如果要编写泛型接口,除非确定该接口中的泛型参数不涉及变体,否则都建议加上out关键字。协变增大了接口的使用范围,而且几乎没有带来什么副作用。

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

编写高质量代码改善C#程序的157个建议——建议43:让接口中的泛型参数支持协变的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

  2. 读书--编写高质量代码 改善C#程序的157个建议

    最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...

  3. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试

    建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...

  4. 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本

    建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...

  5. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  6. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

  7. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  8. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...

  9. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

随机推荐

  1. ui-router 1.0以上的 $stateChangeStart

    ui-router transitionhooks 统一控制路由跳转, 前台控制如果没有登录就跳转到登录页面, 当然也可以在后台控制, 如果没有登录就返回对应的错误码, 然后在response中直接跳 ...

  2. Android 中jar包封装及调用-转

    在android开发过程中,我们经常会有这种需求,自己开发一个类库jar包,提供给别人调用. 即把项目A封装成jar包,供项目B调用,而在项目B中调用项目A的activity的时候问题就出现了:找不到 ...

  3. junit基础学习

    学习地址一:http://blog.csdn.net/andycpp/article/details/1327147/ 学习地址二:http://blog.csdn.net/zen99t/articl ...

  4. 减少CXF日志打印

    场景:项目中引用cxf发布服务,服务调用产生的日志实在是太多了,实在是不能忍 官方文档:http://cxf.apache.org/docs/debugging-and-logging.html#De ...

  5. VCS (版本控制系统)

    1.什么是VCS? 版本控制系统(version control system),是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.版本控制系统不仅可以应用于软件源代码的文本文件, ...

  6. 微信小程序只之全局存储

    全局变量 app.globalData 本地缓存 wx.setStorageSync(KEY,DATA) wx.getStorageSync(KEY) wx.getStorageInfoSync wx ...

  7. Java 对象和实例的区别

    本来我以为是一样的,其实是不一样的 参看:http://www.blogjava.net/dreamstone/archive/2011/06/03/101733.html

  8. 2014.8.27 Vs2005宏的使用

    终于知道怎么像在Word里那样使用宏了! 1.vs2005必须装补丁1 2.在C:\Program Files (x86)\Common Files\microsoft shared\VSA\8.0\ ...

  9. Android 学习 - Telnet 控制AVD

    启动Android Virtual Device之后,使用telnet,可以方便地控制AVD. 首先,获取端口号.启动AVD后,在标题栏上方会出现端口号:设备名,在下面的截图中为5554:N4-15- ...

  10. JDBC概述及连接数据库

    一.JDBC简介:  JDBC(Java Data Connectivity,java数据库连接)是一种用于执行sql语句的JavaAPI,可以为多种关系数据库提供统一访问,它由一组用Java语言编写 ...