大家一起学泛型(一)

 

从简单的例子开始

有一天恒锐召开运动会,技术部要出两个跳高运动员,经理对我说,在小姜和孙晰锐中间选一个吧,你写一个方法,选出他们中最高那个参加。于是我写了如下代码:

跳高运动员实体类
public class Jumper 

// 姓名 
private string mName; 
// 身高 
private int mHeight; 
public string Name { 
get { return this.mName; } 


public int Height { 
get { return this.mHeight; } 


public Jumper( string name, int height) { 
this.mName = name; 
this.mHeight = height; 


选拔方法
public Jumper WhoIsHigher(Jumper jumper1, Jumper jumper2) 

if (jumper1.Height > jumper2.Height) 

return jumper1; 

else 

return jumper2; 

}

过了几天,增加了体育项目,技术部要出两个举重运动员,经理对我说,在于泽龙和刘志允中间选一个吧,你写一个方法,选出他们中最重的那个参加。于是我又写了如下代码:

举重运动员实体类
public class WeightLifter 

// 姓名 
private string mName; 
// 体重 
private int mWeight; 
public string Name { 
get { return this.mName; } 


public int Weight { 
get { return this.mWeight; } 


public WeightLifter( string name, int weight) { 
this.mName = name; 
this.mWeight = height; 


选拔方法
public WeightLifter WhoIsWeighter(WeightLifter Lifter1, WeightLifter Lifter2) 

if (Lifter1.Weight > Lifter2.Weight) 

return Lifter1; 

else 

return Lifter2; 

}

过了几天,又增加了许多体育项目,经理让我根据不同条件选拔选手,比如根据力量最大,步伐最大......然后我崩溃了...

改进的方法
public object WhoIsBetter(object obj1, object obj2) 

object result = obj2;
switch (obj1.GetType().ToString())
{
case "Generic.Jumper":
if (((Jumper)obj1).Height > ((Jumper)obj2).Height)
{
result=obj1;
}

break;
case "Generic.WeightLifter":
if (((WeightLifter)obj1).Weight > ((WeightLifter)obj2).Weight)
{
result=obj1;
}

break;
case "System.Int32":
if (((System.Int32)obj1).CompareTo(obj2) > 0)
{
result=obj1;
}

break;
}

return result;
}

弱点1:方法的重用性

假设我们要让WhoIsBetter方法支持更多类型,支持以后提出的新需求,那么就要不断扩展方法的内部代码,增加了维护成本。

弱点2:类型安全问题

如果上面的代码我把跳高运动员和举重运动员比较,就会出现异常。

弱点3:装箱拆箱导致的性能问题

if (((System.Int32)obj1).CompareTo(obj2) > 0 )

当向WhoIsBetter方法中传递int参数时,object转换为int导致了拆箱操作:

泛型出马,一个顶俩

泛型的解决方案
public class Compare<T> 

public T WhoIsBetter(T t1, T t2) 

if (t1.CompareTo(t2) > 0) 

return t1; 

else 

return t2; 


}
泛型引用
Jumper jumper1 = new Jumper( "小姜" , 160 ); 
Jumper jumper2 = new Jumper( "孙晰锐" , 180 ); 

WeightLifter lifter1 = new WeightLifter( "于泽龙" , 120 ); 
WeightLifter lifter2 = new WeightLifter( "刘志允" , 180 ); 

Console.WriteLine(( new Compare<Jumper>().WhoIsBetter(jumper1, jumper2)).Name); 
Console.WriteLine(( new Compare<WeightLifter>().WhoIsBetter(lifter1, lifter2)).Name);
泛型与非泛型比较
  非泛型 泛型
代码的简洁程度 如果参数类型过多的话,更繁琐 如果参数类型过多的话,更简洁
性能 当涉及到大量的装箱和拆箱操作时,性能较差 当涉及到大量的装箱和拆箱操作时,性能较优
编写的难易程度 易于编写,参数类型更具体 比较难编写,因为它更抽象
维护的难易程度 类型增加时需要不断的增加编码 易于维护

泛型约束

在泛型类型定义中,where 子句用于指定对下列类型的约束:这些类型可用作泛型声明中定义的类型参数的实参。

public class Compare<T> where T : IComparable

where T : IComparable ,这段代码表示对T的类型约束,表示参数T必须实现了IComparable接口(定义一种特定于类型的通用比较方法,值类型或类通过实现此方法对其实例进行排序)。

posted @ 2014-09-10 13:53  dlmuzjq  阅读(152)  评论(0编辑  收藏  举报