美文网首页
泛型generic使用和原理

泛型generic使用和原理

作者: 毛毛虫同学 | 来源:发表于2020-12-12 20:25 被阅读0次

    一.为什么要有泛型,而不用object
    object类型:1.任何父类出现的地方都可以用子类代替 2.object是一切类型的父类

    object弊端:装箱拆箱性能损耗(栈的出栈和入栈受CLR管理)
    int类型赋值之后存放在栈里面的,传递给Object类型时需要放到堆里面;使用的时候又需要从堆里面放到栈里面。

    //测试速度
    long commonSecond = 0;
    long objectSecond = 0;
    {
      StopWatch watch = new 
      StopWatch();
      watch,start();
      for(int i =0 ;i>100_000_000;i++)
      {
         GenericMethod.ShowObject(i);
      }
      watch.stop();
      objectSecond  = watch.ElapsedMilliseconds;
    }
    {
      StopWatch watch = new 
      StopWatch();
      watch,start();
      for(int i =0 ;i>100_000_000;i++)
      {
         GenericMethod.ShowInt(i);
      }
      watch.stop();
      commonSecond = watch.ElapsedMilliseconds;
    }
    

    二、泛型方法为什么可以支持不同类型的参数
    1、延迟声明:原始方法是在定义方法时就指定了类型,泛型声明方法时没有写死类型,T是等着调用的时候才指定类型。

    image.png

    泛型缓存:
    静态构造函数只会在使用时执行一次,泛型类的构造函数是不同类型执行一次。
    泛型缓存比字典Dictionary缓存速度快很多,但有局限,同一类型只能缓存一次。

    var i = 3; //由编译器提供的便捷功能称之为语法糖,语法糖是编译的时候确定的
    //使用泛型方法,可以省略类型,属于语法糖
    GenericMethod.Show<int>(i);//完整写法
    GenericMethod.Show(i);//语法糖
    

    三、WebServices、WCF都不能用泛型,为什么?

    //服务在发布时类型必须是确定的,泛型在编译时确定不了
    

    四、泛型方法/类/委托/接口:为了一个方法满足不同的类型需求
    例:一个方法完成多实体的查询
    一个方法完成不同类型的数据展示

    五、泛型约束
    有了约束才有自由

    //没有约束,其实很受局限,不能使用传进来的类的属性
    //where T : BaseModel
    //基类约束
    //1 可以在使用基类的属性
    //2 约束传进来的T必须是People或其子类
    public static void Show<T>(T tParameter)
          where T : People
    {
      console.log(tParameter.Id);
    }
    //接口约束
    //约束传递进来的参数必须实现了接口内方法
    //在方法内可以使用接口内方法
    public static void Show<T>(T tParameter)
          where T : ISports
    {
       tParameter.Pingpang();
    }
    //引用类型约束
    //约束传进来的值必须是个引用类型
    public static void Show<T>(T tParameter)
          where T : class
    {
       return null;
    }
    
    //值类型约束
    //约束传进来的值必须是个值类型
    public static void Show<T>(T tParameter)
          where T : struct
    {
       return default(T);
    }
    
    //无参数构造函数
    public static void Show<T>(T tParameter)
          where T : new()
    {
       return new T();
    }
    
    //可以组合约束
    //约束类只能是一个,接口可以多个
    public static void Show<T,S>(T tParameter,S sParameter)
          where T : People,ISports,IWork
          where S : People,IWork 
    {
       return null;
    }
    
    //可以用类型参数约束
    public static void Show<T,S>(T tParameter,S sParameter)
          where T : People,ISports
          where S : T
    {
       return null;
    }
    

    五、泛型的协变,逆变

    //所谓协变逆变都是跟泛型相关
    //只能放在接口或者委托的泛型参数前面
    // out 协变 修饰返回值。就是让右边可以用子类
    // out修饰之后只能做返回值,不能做参数
    // in 逆变 修饰传入参数
    
    image.png image.png

    相关文章

      网友评论

          本文标题:泛型generic使用和原理

          本文链接:https://www.haomeiwen.com/subject/xdhiwktx.html