C# -- 泛型(2)
通过前面的文章我们知道“泛型”是个“形容词”,并且了解了 “泛型类” 和 “泛型数组” ,下面我们来看看泛型的其它的使用方式。
上一篇: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)的更多相关文章
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- C#4.0泛型的协变,逆变深入剖析
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...
- 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)
建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...
- 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- C#泛型详解(转)
初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...
- C# 泛型
C# 泛型 1.定义泛型类 在类定义中包含尖括号语法,即可创建泛型类: class MyGenericClass<T> { //Add code } 其中T可以遵循C#命名规则的任意字符. ...
- java8中lambda表达式的应用,以及一些泛型相关
语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...
- java 泛型
1.Student stu =tool.getObj();右边得到的是Object类型,需要向下转型,强转换. 2. 3. 4.泛型方法不能被静态修饰这样写 5.如果想定义定义静态泛型方法,只能这样写 ...
- Java泛型的历史
为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...
随机推荐
- Ajax验证用户名
用Ajax验证用户名: 接口: get guestbook/index.php m : index a : verifyUserName username : 要验证的用户名 返回 { code : ...
- (转)使用PowerDesigner生成HTML功能
本文转载自:http://www.cnblogs.com/CowboyProgrammer/archive/2009/04/28/1445423.html 使用PowerDesigner设计数据库关系 ...
- 转: SQL中的where条件,在数据库中提取与应用浅析
SQL中的where条件,在数据库中提取与应用浅析 http://hedengcheng.com/?p=577 1问题描述 一条SQL,在数据库中是如何执行的呢?相信很多人都会对这个问题比较感兴趣.当 ...
- form表单使用(博客系统的登陆验证,注册)
先从小的实例来看form的用法 登陆验证实例,来看form的常规用法 1. forms.py # 用于登陆验证验证 from django.core.validators import RegexVa ...
- 红黑树(Red-Black Tree)
概念解析: 红黑树是一种自平衡二叉查找树(self-balancing binary search tree).因此,红黑树本身就是二叉树的一个变种.典型的用途是实现关联数组(Associative ...
- python's eighth day for me
f : 变量,f_obj, file, f_handler,...文件句柄. open : windows 的系统功能. windows 默认编码方式:gbk. Linux 默认编码方式:utf ...
- 不使用sudo命令执行docker
不使用sudo命令执行docker 2015-09-11 11:03:05 王春生 8049 最后编辑:王春生 于 2015-09-11 12:18:30 简介:本篇文章介绍如何不使用sudo命 ...
- DRF - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件
一.序列化组件 基于上篇随笔的表结构 , 通过序列化组件的ModelSerializer设计如下三个接口 : GET 127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{} ...
- Java之IO输入输出
首先介绍File类: 我们直接上代码: package com.learn.chap10.sec02; import java.io.File; import java.io.IOException; ...
- Java面向对象-对象的多态性
Java面向对象-对象的多态性 Java中的多态性表现: 1,方法的重载和重写(覆盖): 2,可以用父类的引用指向子类的具体实现,而且可以随时更换为其他子类的具体实现: 我们先搞个父类Animal: ...