如此强大的C#泛型

一、泛型概念

C# 语言和公共语言运行时 (CLR) 在 2.0 版本中添加了泛型。泛型将类型参数的概念引入 .NET Framework,这样就可以设计具有相同特征的类和方法:在客户端代码声明并初始化这些类和方法之前,这些类和方法会延迟指定一个或多个类型(使用占位符~3:数字代表类型参数个数)

二、泛型的作用

使用泛型类型可以最大限度地重用代码保护类型安全性以及提高性能。泛型最常见的用途是创建集合类 List< int>。

1.泛型分类:

泛型接口、泛型类泛型方法、泛型事件和泛型委托

2.泛型的好处

(1)增加类型的安全性
(2)提高代码的重用

三、泛型的使用

(一)泛型类

1.创建泛型类

在这里插入图片描述

2.案例:
//泛型类
    class MyList<T>
    {
        T[] stack; //声明数组
        int size; //数组长度
        int stacPoint; //当前位置指针(索引)
        public MyList(int length)
        {
            this.size = length;
            stack = new T[size];
            stacPoint = -1;
        }
        // 入栈
        public void Add(T item)
        {
            if (stacPoint>=size) //如果超过数组长度
            {
                Console.WriteLine("集合已满");
            }
            else
            {
                stacPoint++;
                stack[stacPoint] = item;
            }
        }
        // 出栈
        public T Pop()
        {
            T data = stack[stacPoint];
            stacPoint--;
            return data;
        }
    }
// 主运行窗口
		static void Main(string[] args)
        {
            //实例化泛型类
            MyList<int> list = new MyList<int>(6);
            //入栈 
            list.Add(1);
            list.Add(2);
            list.Add(3);
            list.Add(4);
            list.Add(5);
            //出栈
            Console.WriteLine(list.Pop()); // 5
            Console.WriteLine(list.Pop()); // 4
            Console.WriteLine(list.Pop()); // 3
            Console.WriteLine(list.Pop());// 2
            Console.WriteLine(list.Pop());// 1
            Console.ReadLine();
        }
3.泛型类的规范:
    public class 类名<T> {类成员....}

(1) T:仅代表一个占位符,用T或者其他字母都行,只要符合C#命名规范都行,但是一般情况用T
(2) T:表示一个通用的数据类型,在使用的时候用实际类型代替
(3)T:泛型类可以在定义中可以包含多个任意类型参数,参数之间使用逗号隔开

    public class 类名<T1,T2,T3,....>{...}

各种类型参数都可以用作成员变量的类型属性方法等成员的返回类型,以及方法的参数类型
以上泛型类的使用,增加了类型安全,实例化时int类型的约束下是不能添加string类型。无需拆箱操作

4.泛型类型的问题

无法为泛型类型赋值初始

因为泛型类型可以理解为泛指所有的数据类型,而所有的数据类型可分为:值类型和引用类型,而且不同的数据类型支持的默认值是不一样的。
注意:
(1) 不能随便假设泛型类型是某种类型,这种类型也许没有构造方法,也许是私有的
(2) 解决方案使用default关键字,如果defalut中指定的类型最终是引用类型则默认是null,如果是值类型那就给值类型对应的默认值,数值就是0.结构类型要根据具体的成员类型确定是0还是null

(二)泛型方法

案例

		static void Main(string[] args)
        {
            Console.WriteLine(Add<int>(11,12));//23
            Console.WriteLine(Add<double>(11.5,12.5));// 24
            //Console.WriteLine(Add<char>('a','b'));//异常实参不为值类型 
            Console.ReadLine();
        }
        //泛型方法
        static T Add<T>(T a,T b) where T : struct
        {
            dynamic a1 = a;  // 设置动态类型   根据程序执行动态获取当前类型
            dynamic b1 = b;
            return a1 + b1;
        }

四、泛型约束

1.泛型约束有哪些

  1. where T : struct 类型参数必须值类型
  2. where T : class 类型参数必须引用类型。 此约束还应用于任何类、接口、委托或数组类型。
  3. where T : unmanaged 类型参数不能是引用类型,并且任何嵌套级别均不能包含任何引用类型成员
  4. where T : new() 类型参数必须具有公共无参数构造函数
  5. where T : <基类名> 类型参数必须是指定的基类或派生自指定的基类
  6. where T : <接口名称> 类型参数必须是指定的接口或实现指定的接口
  7. where T : U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

2.案例

 	static void Main(string[] args)
    {
            MyGenericClass<int, Course, Teacher> myGener = new MyGenericClass<int, Course, Teacher>();
            myGener.ProductList = new List<Course>()
            {
                new Course(){CourseName="ASP.NET",Period=6},
                new Course{CourseName="WEB",Period=5}
            };
            Course c = myGener.GetClass(0);
            Console.WriteLine($"{c.CourseName}课程的周期{c.Period}");
            Console.ReadLine();
   }
   //泛型类
   class MyGenericClass<T1, T2, T3>
        where T1:struct //值类型
        where T2:class  //引用类型 (还包含:类,接口,委托,数组)
        where T3:new () //无参数构造函数
    {
        public List<T2> ProductList { get; set; } //声明以T2集合为类型的属性
        public T3 Teachers { get; set; } //声明以T3为类型的属性
        //声明以T2 为返回类型、T1类型为参数,的方法
        public T2 GetClass(T1 num)
        {
            dynamic a = num; //根据T1获取到a的数据类型
            return ProductList[a]; //返回数组中a索引对应的数据
        }
    }
    //参数类 T2:代表所学的科目类
    class Course 
    {
        /// <summary>
        /// 课程名称
        /// </summary>
        public string CourseName { get; set; }
        /// <summary>
        /// 学习周期
        /// </summary>
        public int Period { get; set; }

    }
    //参数类 T3:代表老师
    class Teacher
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 授课数量
        /// </summary>
        public int Count { get; set; }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值