• 大家一起学泛型(一)


    从简单的例子开始

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

    跳高运动员实体类
    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接口(定义一种特定于类型的通用比较方法,值类型或类通过实现此方法对其实例进行排序)。

  • 相关阅读:
    IDEA+SpringMVC+Spring+Mybatis
    WSDL详解
    cxf的使用
    cxf使用wsdl文件生成代码
    给你的博客加上“Fork me on Github”彩带(转)
    老毛桃pe装机工具一键还原系统
    老毛桃pe装机工具备份系统
    java项目中classpath路径到底指的是哪里?
    this.class.getClassLoader().getResourceAsStream与this.class.getResourceAsStream
    Eclipse中导入项目后js报错解决方法(转未解决问题)
  • 原文地址:https://www.cnblogs.com/zjq1989/p/3964295.html
Copyright © 2020-2023  润新知