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 ...
随机推荐
- android中HttpClient的应用(POST方法)
首先在http://hc.apache.org/downloads.cgi下载HttpClient包 直接看代码 import android.os.Handler; import android.o ...
- IaaS vs PaaS vs SaaS
在云计算的早期阶段,企业面临的最大问题是他们是否应该使用公共云服务.如今,几乎所有的组织都在采用一些公共云服务.更重要的问题是企业应该使用哪种云服务:基础设施即服务(IaaS),平台即服务(PaaS) ...
- php excel 设置单元格格式为文本格式
学习源头:https://www.cnblogs.com/php-linux/p/6179442.html 解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制 ...
- juc原子类之五:AtomicLongFieldUpdater原子类
概要 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法 ...
- pt工具之pt-archiver
# tar -zxvf percona-toolkit-2.2.17.tar.gz# yum -y install perl perl-IO-Socket-SSL perl-DBD-MySQL per ...
- PCB上 如何显示 汉字
原理图上有汉字,那如何在PCB上显示汉子呢 ? 而不至于显示乱码 按如下操作 ,双击乱码 ,进入设置模式 设置好后,显示的字体样式.
- ARM-Linux移植之(三)——init进程启动流程分析
我们通常使用Busybox来构建根文件系统的必要的应用程序.Busybox通过传入的参数来决定执行何种操作.当init进程启动时,实际上调用的是Busybox的init_main()函数,下面我们来分 ...
- Py修行路 python基础 (十八) 反射 内置attr 包装
一.isinstance 和 issubclass1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象.2.issubclass(sub, super)检查sub类是否是 ...
- PHP判断当前协议是否为HTTPS
function is_https() { if ( !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'o ...
- 配置key认证登陆Ubuntu (上)
每一个看似轻松的结果背后都有不为人知的辛酸.又是一件小事,结果折腾了一天. 上接配置好SSH 和Samba后,开始了Python编程实践.由于实在不大会用Vim, 所以最后的编程环境实际上在Windo ...