C#学习笔记-Generic泛型和泛型约束

泛型(Generic)

泛型集合List<T>、Dictionary<k,v>   所在命名空间:System.Collections.Generic;

比较非泛型:ArryList,Hastable      所在命名空间:System.Collections

非泛型集合ArryList里面可以添加任意类型,添加方便的对于数据本身来讲,是非常不安全的。

因为我们开发中很多时候,这些是不可控的。其次,还存在拆装箱的问题。

装箱:将值类型的元素,放到集合中会被转换成object类型。这个过程就叫装箱。

拆箱:将一个集合中的元素取出来,但是这个元素本质是值类型,必须强制类型转换。

弊端:程序中如果有大量的数据进行拆箱装箱,会很影响程序的性能。

1、泛型出现-->泛型概念:泛型是一种程序特性,定义的时候,是对这个类型不作出明确的规定,

    但是当使用的时候,必须明确规定,并且不能改变。

2、泛型出现的场合:泛型集合、泛型方法、泛型类、泛型委托...
 

    //编写一个出入站的泛型类
    public class MyStack<T>
    {
        //准备一个泛型数组
        private T[] stack;
        //泛型位置
        private int stackPoint;
        //泛型数组大小
        private int size;

        public MyStack(int size)
        {
            this.size = size;
            this.stackPoint = -1;
            stack = new T[size];
        }
        /// <summary>
        /// 元素入栈
        /// </summary>
        /// <param name="item"></param>
        public void Push(T item)
        {
            if (stackPoint > size)
            {
                Console.WriteLine("数组入栈已满");
            }
            else
            {
                stackPoint++;
                this.stack[stackPoint] = item;
            }
        }
        /// <summary>
        /// 元素出栈
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            T data = this.stack[stackPoint];
            stackPoint--;
            return data;
        }
    }

动态类型

在使用泛型类型时,不明确成员类型,不能new或者赋值null(值类型),使用default关键字可以解决这一问题。在使用var推断对象类型时,推断的对象类型必须明确,不能为泛型。

  class Generic<T1,T2>
    {
        private T1 data1;
        private T2 data2;

        public Generic()
        {
            //data1 = new T1(); 没有确定是引用类型,不能使用new
            //data1 = null; 很多情况下,值类型是不能为null


            data1 = default(T1);//使用default,如果是引用类型要则赋值null,如果是值类型就给值类型默认值
            data2 = default(T2);
        }

    }

泛型方法中如果不明确参数或者返回值类型,编译时解析的话,会引起程序报错,使用dynamic运行时做解析 ,可以处理这一问题。

    public T2 BuyCourse(T1 position)
        {
            // return this.ProductList[position];  //直接写是错误的
            // var index = position;     //因为我们不能特别明确的知道T1是什么类型,使用var的时候,后面的类型必须是明确的

            dynamic index = position;//dynamic是在运行时解析对象类型,在编译阶段是不解析的。
            return this.ProductList[index];  
        }

泛型约束

目的:就是对泛型类型做出数据类型的要求,或者其他的条件。

    public class MyGenericCalss1<T1, T2, T3,T4>
    where T1 : struct  //解释:T1必须是值类型
    where T2 : class  //解释:T2必须是引用类型
    where T3 : new()  //解释:T3这个类型中,必须有一个无参数的构造方法,这个约束必须放到最后
    where T4: Imeeting //解释:T4类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
        //其他的类型:基类型、接口类型...

参考资料:https://www.cnblogs.com/arxive/p/6179972.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值