通过前面的文章我们知道“泛型”是个“形容词”,并且了解了 “泛型类” 和 “泛型数组” ,下面我们来看看泛型的其它的使用方式。

上一篇:C# -- 泛型(1)

<1>.泛型方法

上一篇文章说到用一个泛型类 SortHelper 来做一个冒泡排序的处理,下面回顾一下之前的代码:

    public class SortHelper<T> where T:IComparable
{
public void BubbleSort(T[] arr)
{
int length = arr.Length;
for (int i = ; i < length-; i++)
{
for (int j = ; j < length--i; j++)
{
if (arr[j].CompareTo(arr[j+])>)
{
T temp = arr[j];
arr[j] = arr[j + ];
arr[j + ] = temp;
}
}
}
}
}

这里我们为了调用 BubbleSort,而将参数T传递给类 SortHelper,假如 SortHelper 类中,除了 BubbleSort 方法之外,还有其他的没有使用到参数T的方法 比如:

    public class SortHelper<T> where T:IComparable
{
public void BubbleSort(T[] arr)
{
//省略
} public void OtherMethod1()
{
//省略
}
//此处省略N个OtherMethod
}

这里有 N 个 OtherMethod方法。

测试-调用 OtherMethod1:

        static void Main(string[] args)
{
SortHelper<int> UserOtherMethod = new SortHelper<int>();
UserOtherMethod.OtherMethod1();
}

在实例化 UserOtherMethod 对象时 必须给 SortHelper 传一个类型参数 这里是 int  。显然这中情况下,我们仅仅是为了 BubbleSort 方法正常使用而定义泛型类,从而强迫其他使用 SortHelper 类其它方法

的实例传递一个参数,很明显这是没必要的,于是这个时候 ’泛型方法‘ 就出现了 ,修改代码如下:

    public class SortHelper2
{
public void BubbleSort<T>(T[] arr) where T:IComparable
{
int length = arr.Length;
for (int i = ; i < length - ; i++)
{
for (int j = ; j < length - - i; j++)
{
if (arr[j].CompareTo(arr[j + ]) > )
{
T temp = arr[j];
arr[j] = arr[j + ];
arr[j + ] = temp;
}
}
}
}
}

总结:

泛型方法和普通方法没多大区别,仅仅在方法名后面加了“<T>”, 接着是括号里面的参数,最后是限定语句。

上述的这种情况,我们通过使用泛型方法,就可以避免每次使用泛型类传参了。

<2>.泛型接口

回顾之前的文章我们 自己写了一个 “cat” 类,并调用了一个接口“IComparable” 代码如下:

    public class cat:IComparable
{
public string name;
public int price; public int CompareTo(object obj)
    {
      cat catT = (cat)obj;
      return this.price.CompareTo(catT.price);
    }
     public cat(string name, int price)
{
this.price = price;
this.name = name;
}
}

这里粉红色标记的部分我们实现了 “IComparable” 接口的 “CompareTo” 方法 这里没有进行装箱和拆箱。

因为cat是引用类型,而且“ return this.price.CompareTo(catT.price) ”这里调用的是 price (int型) 的 ComparaTo 方法,右键对int转到定义查看代码。

这里可以清楚的看到int类型实现了 IComparable 与 IComparable<int> 这两个接口,也就是说它分别实现了这两个接口的 ComparaTo() 方法,那这里又是调用那个接口的 ComparaTo() 方法呢?

实际上这里传过来的参数是int类型,那么优先调用的是 ComparaTo(int value) 方法,这样就避免了不必要的装箱拆箱过程了。

上图中是.NET 中 int 类型实现 IComparable 接口的 ComparaTo(object value) 方法,不难看出“红箭头”标记部分是执行装箱拆箱操作的过程。

下图是 int类型实现泛型版本的 IComparable<int> 的 ComparaTo(int value) 方法,如果对2种方法进行大量重复操作,不难发现使用泛型接口实现的方法性能比较好。

总结:

程序设计中应该尽量避免装箱和拆箱操作,为了避免多次装箱拆箱造成的性能影响 ,通过上面的例子我们可以知道使用泛型接口可以有效的避免这个问题:使用 IComparable<T> 而不使用 IComparable,这样可以避免值类型的装箱和取消装箱操作。

出自: Keiling_J'Blog http://www.cnblogs.com/keiling/

C# -- 泛型(2)的更多相关文章

  1. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  2. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

  3. C#4.0泛型的协变,逆变深入剖析

    C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  6. C#泛型详解(转)

    初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...

  7. C# 泛型

    C# 泛型 1.定义泛型类 在类定义中包含尖括号语法,即可创建泛型类: class MyGenericClass<T> { //Add code } 其中T可以遵循C#命名规则的任意字符. ...

  8. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

  9. java 泛型

    1.Student stu =tool.getObj();右边得到的是Object类型,需要向下转型,强转换. 2. 3. 4.泛型方法不能被静态修饰这样写 5.如果想定义定义静态泛型方法,只能这样写 ...

  10. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

随机推荐

  1. HTTP-POST

    POST方式:用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列中请求URI所指定资源的附加新子项,Post被设计成用统一的方法实现下列功能: 1:对现有资源的解释: 2:向电 ...

  2. 使用Spring和Tomcat发布CXF REST WebService

    与发布SOAP WS一样, 同样需要在web.xml文件中配置CXFServlet: <!--cxf的Servlet--> <servlet> <servlet-name ...

  3. java多线程实现每隔500毫秒输出一个数字

    总结:主要是利用多线程来进行控制它输出的速度,而且这里要处理异常,这个异常我是这样处理的 1.首先写完一个for循环后,写这个:Thread.currnetThread().sleep(500); 然 ...

  4. chrome浏览器手动添加印象笔记剪藏插件

    标签(空格分隔): chrome浏览器,日常办公 一直为每次从网页上复制内容之后,还需要再去复制对应的网址,倍感麻烦.之前偶尔这样操作还可以,最近在学习新东西,要保留下来的网页实在太多,而且不利于分类 ...

  5. Linux性能监测:磁盘IO篇

    磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴.寻轨等.访问硬盘和访问内存之间的速度差别是以数量级来计算的,就 ...

  6. babel-preset-latest使用介绍

    本文介绍babel中的babel-preset-latest插件 简介 该插件的作用是包含了每年的js代码转换规则 默认包含es2015,es2016,es2017,默认对这些代码都会进行转码,从而方 ...

  7. 第五章 bean的加载(待续)

    ·············

  8. Java微信公众平台开发--番外篇,对GlobalConstants文件的补充

    转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...

  9. 切面(Aspect)获取请求参数和返回值

    @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 接收到请求, ...

  10. webrtc系列文章

    WEBRTC RTP/RTCP协议族 2017-02-22 20:15 阅读(144) 评论(0) WebRTC 基于GCC的拥塞控制(下) 2017-02-22 15:44 阅读(108) 评论(0 ...