• C#:泛型


    泛型:拥有让多种类型共享一组代码的能力。

    • 在声明语句中,在方法名、类名、接口名、结构名、委托类型名后,使用一个"<占位符1,占位符2>"(如:List、Action<T1,T2>)来替代真实的数据类型这就完成了泛型的创建
    • 这些占位符被称为类型参数、使用了类型参数后方法变成了泛型方法、类变成了泛型类、接口变成了泛型接口...
    • 泛型类、泛型方法等不能直接使用,只有用真实的数据类型代替类型参数:如 List、Action<string,int>...才可以使用--而这一过程被称为特化
    static void ShowInfo(int param)
    {
        Console.WriteLine($"{param.GetType().FullName}--{param}");
    }
    static void ShowInfo(string param)
    {
        Console.WriteLine($"{param.GetType().FullName}--{param}");
    }
    static void ShowInfo(double param)
    {
        Console.WriteLine($"{param.GetType().FullName}--{param}");
    }
    

    通过观察,便可看出:上面的方法除了操作的数据类型不同外,在功能上是相同的;可以将代码改写成下面形式:
    通过将方法声明为泛型方法,无论是预定义类型、用户自定义类型等,都可以共享同一组代码了。

    static void ShowInfo<T>(T param)
    {
        Console.WriteLine($"{param.GetType().FullName}--{param}");
    }
    

    泛型类

    声明泛型类

    • 在类名后面放一对尖括号
    • 在尖括号中可以放置一个或多个占位符来表示希望提供的类型,这些占位符也成为类型参数
    • 在类体中,可以使用类型参数替代实际类型
    class  MyStack<T>
    {
        private int startPointer = 0;
        private T[] stackArray;
        public void Push(T item)
        {
            //压栈
        }
        public T Pop()
        {
            //弹栈
            return stackArray[stackArray.Length-1];
        }
    }
    

    使用泛型类

    • 为泛型参数提供实际的数据类型替补空缺--否则我们无法使用泛型类
    • 声明特化了的泛型实例
    • 使用实例调用方法
    static void Main(string[] args)
    {
        //使用int来替代T
        MyStack<int> myStack;
        //像普通类型创建实例那样,创建Mystack<int>类型实例
        myStack = new MyStack<int>();
        //调用方法
        myStack.Push(11);
        int popItem = myStack.Pop();
        Console.ReadLine();
    }
    

    泛型能够提高性能

    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Console.WriteLine($"开始:{stopwatch.ElapsedMilliseconds}");
            for (int i = 0; i < 1000; i++)
            {
                ShowInfo(i);
            }
    
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
            stopwatch.Restart();
            Console.WriteLine($"重新开始:{stopwatch.ElapsedMilliseconds}");
            for (int i = 0; i < 1000; i++)
            {
                ShowInfo<int>(i);
            }
    
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
            Console.ReadLine();
        }
    
        static void ShowInfo<T>(T param)
        {
            Console.WriteLine($"{param.GetType().FullName}--{param}");
        }
    
        static void ShowInfo(int param)
        {
            Console.WriteLine($"{param.GetType().FullName}--{param}");
        }
    }
    

    运行结果:

    类型参数的约束:包括where子句和约束类型

    //使用where子句,使类型参数T继承ICompare接口,这样parma1便可以使用CompareTo方法了
    static bool IsLessThan<T>(T param1, T param2) where T : IComparable
    {
        return param1.CompareTo(param2) < 0 ? true : false;
    }
    

    where子句

    • 如果需要对于单个类型参数,提供多个约束,则使用","隔开
    static bool IsLessThan<T1,T2>(T1 param1, T2 param2) where T1 : struct,IComparable
    {
        return param1.CompareTo(param2) < 0 ? true : false;
    }
    
    
    • 如果需要对多个类型参数提供约束,则使用多个where子句--注意:where之间不需要使用","
    static bool IsLessThan<T1, T2>(T1 param1, T2 param2) where T1 : struct, IComparable
                                                         where T2 : class
    {
        return param1.CompareTo(param2) < 0 ? true : false;
    }
    

    约束类型:按照出现顺序约束一共下面几种

    • 主约束(只能有一个):
      • 类名---表明类型参数属于该类型或者继承了该类型
      • class---表明类型参数是一种引用类型
      • struct---表明类型参数是一种值类型
    • 次要约束(可以多个):
      • 接口名---此约束表明类型参数是实现了该接口的类型
    • 构造函数约束:多个约束时放在最后面
      • new()---此约束表明类型参数是一种带有公共无参构造函数的类型

    下面展示一下约束类型的使用(仅为展示用,实际中可能并不会这样写)

    static bool IsLessThan<T1, T2>(T1 param1, T2 param2) where T1 : Student, IComparable
                                                         where T2 : class,new()
    {
        return param1.CompareTo(param2) < 0 ? true : false;
    }
    

    以上便是对泛型的概念的总结,关于泛型还有很多未总结的知识点,放在后面再写。

  • 相关阅读:
    值类型和引用类型区别
    json数据类型
    转:不再以讹传讹,GET和POST的真正区别
    简单投票系统学到的一些东西
    jq 全选和反选以及判断那条被选中
    PHP中获取当前页面的完整URL
    jq div鼠标放上、离开马上展开、收缩方法
    js 删除确定
    mysql 存储过程
    js 闭包原理理解
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/13943210.html
Copyright © 2020-2023  润新知