建议32:总是优先考虑泛型

泛型的优点是多方面的,无论泛型类还是泛型方法都同时具备可重用性、类型安全性和高效率等特性,这是非泛型和非泛型方法无法具备的。

以可重用性为例:

  1. class MyList
  2. {
  3. private int[] items;
  4.  
  5. public int this[int i]
  6. {
  7. get { return items[i]; }
  8. set { this.items[i] = value; }
  9. }
  10.  
  11. public int Count
  12. {
  13. get { return items.Length; }
  14. }
  15. ///省略其他方法
  16. }

该类型只支持整型,如果要让类型支持字符串,有一种方法是重新设计一个类。但是这两个类型的属性和方法都是非常接近的,如果有一种方法可用让类型接收一个通用的数据类型,这样代码就可以复用了,同时类型也只要一个就够了。泛型完成的就是这样一个功能。泛型实现如下:

  1. class MyList<T>
  2. {
  3. private T[] items;
  4.  
  5. public T this[int i]
  6. {
  7. get { return items[i]; }
  8. set { this.items[i] = value; }
  9. }
  10.  
  11. public int Count
  12. {
  13. get { return items.Length; }
  14. }
  15.  
  16. ///省略其他方法
  17. }

可以把T理解为一个占位符,在C#泛型编译生成的IL代码中,T就是一个占位符的角色。在运行时,即时编译器(JIT)会用实际代码中输入的T类型来代替T,也就是说,在由JIT生成的本地代码中,已经使用了实际的数据类型。我们可以吧MyList<T>和MyList<T>视作两个不同类型,但是,这仅是对本地代码而言,对应实际的C#代码,它仅仅拥有一个类型,那就是泛型类型MyList<T>。

如果不用泛型来实现,另一种方法是让MyList的编码从object的角度去设计。在C#的世界中,所有类型(包括值类型和引用类型)都是继承自object,如果让MyList足够通用,就需要让MyList针对object编码,代码如下:

  1. class MyList
  2. {
  3. private object[] items;
  4.  
  5. public object this[int i]
  6. {
  7. get { return items[i]; }
  8. set { this.items[i] = value; }
  9. }
  10.  
  11. public int Count
  12. {
  13. get { return items.Length; }
  14. }
  15. ///省略其他方法
  16. }

这会让下面的代码编译通过:

list[0]=123;

list[1]="123";

由上面两行代码带来的问题就是非类型安全性。让类型支持类型安全,可以让程序在编译期间就过滤掉部分Bug,同时,也能让代码避免“转型为object类型”或“从object转型为实际类型”所带来的性能损耗。尤其是当操作类型是值类型时,还会带来装箱拆箱的性能损耗。

泛型为C#语言带来了革命性的变化,FCL之后的很多功能都是借助泛型才得到很好的实现,如LINQ。LINQ借助于泛型和扩展方法,有效地丰富了集合的查询功能,同时避免了代码爆炸并提升了操作性能。我们在设计自己的类型时,应充分考虑到泛型的优点,让自己的类型成为泛型类。

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

编写高质量代码改善C#程序的157个建议——建议32:总是优先考虑泛型的更多相关文章

  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. Six Basic Functional Areas of Spring

  2. 18.Selenium+Python案例 -- 豆瓣

    一.具体代码实现: from selenium import webdriver driver = webdriver.Firefox() driver.get('https://www.douban ...

  3. Shell脚本基础知识详细介绍(一)

    Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释和执行用户输入的命令:作为程序设计语言,它定义了各种 ...

  4. mybatis-spring升级导致的异常

    先记录一下,已被后面排查问题 升级前pom.xml依赖信息: <dependency> <groupId>org.mybatis</groupId> <art ...

  5. thinkphp中的dump方法

    感受一下,调试. 1.print_r() 2.var_dump() 3.再看看thinkphp中的dump方法 清晰多了!真实够傻的,今天才发现有这么好的调试方法.

  6. 前端学习---css基本知识

    css基本知识 我们先看一个小例子: <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  7. 基于JNI,JAVA 调用 C++入门

    1.步骤一览 2.步骤详情 2.1. 编写Java类 native package com.ibugs.jni; /** * * @author i_bugs * */ public class CP ...

  8. STM32与PC机串口通讯

    有时要将板子的信息输出到电脑上来调试之类的,或者把传感器收集到的数据显示到电脑. 当然了,这只是最基本的串口通信,简单的说,是有一根USB线连着的. mbed上并没有能显示printf的功能.需要自己 ...

  9. 一.lock的使用

    使用ReentrantLock类 ReentrantLock类在扩展功能上更加强大,比如嗅探锁定,多路分支通知.而且在使用上也比synchronized更加灵活 调用ReentrantLock对象的l ...

  10. Halcon学习之二:摄像头获取图像和相关参数

    1.close_all_framegrabbers ( : : : ) 关闭所有图像采集设备. 2.close_framegrabber ( : : AcqHandle : ) 关闭Handle为Ac ...