C#泛型 详细介绍

泛型:把类型做到通用—>代表着动态

  1. 什么是泛型{通用的模板}
  2. 如何声明和使用泛型
  3. 泛型的好处与原理
  4. 泛型类、泛型方法、泛型接口、泛型委托
  5. 泛型约束
  6. 协变 逆变
  7. 泛型缓存
    总结:
    【1】泛型的用处–让我们泛型类、泛型方法、泛型接口、泛型委托这些更–通用
    【2】次要:约束用的不是很多。太通用,安全性不是很高,所以需要进行约束
    【3】了解性的内容:协变逆变

以下是关于泛型的例子,里面有详细的介绍
关于泛型总结如上↑,整体细节如下↓

using System;
using System.Collections.Generic;

namespace _13泛型
{
    public class Program
    {
        static void Main(string[] args)
        {
            //1.什么是泛型?
            List<string> vs = new List<string>() { "编程", "测试", "AI" };
            foreach (var item in vs)
            {
                Console.WriteLine(item);
            }
            //object类型做数据转换的时候有拆箱装箱的操作,有性能损耗,建议少用
            List<object> objList = new List<object>() { };
            List<List<string>> vs1 = new List<List<string>>();
            Console.WriteLine("-----------泛型private KeyValuePair<TKey, TValue> current----------");
            //泛型private KeyValuePair<TKey, TValue> current; 键/值对(泛型字典)
            //TKey不能重复
            Dictionary<int, string> keyValuePairs = new Dictionary<int, string>();
            keyValuePairs.Add(1, "C#基础语法");
            keyValuePairs.Add(2, "C#中级语法");
            keyValuePairs.Add(3, "java高级语法");
            foreach (var item in keyValuePairs)
            {
                Console.WriteLine(item.Key.ToString() + "--" + item.Value);
            }
            bool isContains = keyValuePairs.ContainsValue("java高级语法");
            keyValuePairs.Remove(2);
            Console.WriteLine(isContains);
            foreach (var item in keyValuePairs)
            {
                Console.WriteLine(item.Key.ToString() + "--" + item.Value);
            }
            Console.WriteLine("---------------------自定义泛型--------------------");
            //自定义泛型(泛型最大的优点就是做到了通用)
            MyGeneric<string> myGeneric = new MyGeneric<string>("这是一个自定义参数");
            myGeneric.Show();
            MyGeneric<int> myGenericInt = new MyGeneric<int>(1000);
            myGenericInt.Show();
            Console.WriteLine("---------------------泛型方法--------------------");
            Show(11111111);
            Show1("泛型方法");

            Console.WriteLine("---------------------泛型约束{条件约束}--------------------");
            //【1】new() 约束--表示T类型只接收带一个无参数的构造函数
            //【2】struct值类型约束
            //【3】class引用类型约束
            //【4】自定义类型约束(基类型约束,接口类型约束)
            //值类型--结构类型stuct--int,double,bool,枚举
            //引用类型--数组,类,接口,委托,object,字符串
            //new() 约束,一定要写在最后面 
            //
            Student student = new Student();
            //IStudent student1 = new IStudent();//不可以进行常见对象
            IStudent student1 = null;
            Show(student);
            ShowStudent(student);
            Student2 student2 = new Student2();
            //ShowStudent(student2);//纯属别的对象,不会被方法接受  要传输规定的类型
            Console.WriteLine("---------------------协变和逆变--------------------");
            People people = new People();
            People people1 = new People();
            Teacher teacher = new Teacher();
            //Teacher teacher1 = new People();
            List<People> listOut = new List<People>();
            //【1】其实从现实中理解,他应该正确才对,但是List<People>类型和List<Teacher>()不是一个类型,从类型的角度来不成立
            //,所以,其实这个是语法规则不支持。.net2.0,3.0的时候才有协变和逆变
            //【2】协变和逆变他是针对接口和泛型委托来说的。离开了他们就没有这个说法。
            //【3】out关键字代表协变,in代表逆变
            //【4】什么情况下使用???在知道自己或别人以后有用到弗雷通过子类实例化,或者子类通过弗雷实例化的
            //的情况下可以out或者in关键字
            //List<People> listOut = new List<Teacher>();

            IListOut<People> listOut1 = new ListOut<People>();
            IListOut<People> listOut2 = new ListOut<Teacher>();//协变

            IListIN<Teacher> listIN = new ListIN<Teacher>();
            IListIN<Teacher> listIN1 = new ListIN<People>();//逆变

            IOutInList<Teacher, People> myList1 = new OutIntList<Teacher, People>();
            IOutInList<Teacher, People> myList2 = new OutIntList<Teacher, Teacher>();//协变
            IOutInList<Teacher, People> myList3 = new OutIntList<People, People>();//逆变

            IOutInList<Teacher, People> myList = new OutIntList<People, Teacher>();//逆变+协变

            Console.ReadKey();
        }

        #region 泛型方法
        public static void Show<T, S, K, D>(T t)
            where D : Student, IStudent, IStudent<T>//基类约束,只能有一个而且要放前面,接口约束可以多个 {where D : Student,Student2, IStudent, IStudent<T>}
            where S : struct
            where T : class, new()
        {
            Console.WriteLine(t);
        }
        // public static void ShowMany<T>(T t)
        //where T : struct, Student//又是值类型又是引用类型是不合理的
        // {
        //     Console.WriteLine(t);
        // }

        // public static void ShowMany<T>(T t)
        //where T : struct, new()
        // {
        //     int i = new int();//是可以创建空间的,不可以重复使用
        //     Console.WriteLine(t);
        // }

        // public static void ShowMany<T>(T t)
        //where T : class, new()//符合常理,同时使用多个条件
        // {
        //     int i = new int();
        //     Console.WriteLine(t);
        // }


        //可以多条件约束
        public static void ShowMany<D, S, T>(D d, S s, T t)
            where D : IStudent
            where S : struct
       where T : class, new()
        {
            int i = new int();
            Console.WriteLine(t);
        }

        public static void ShowStudent<T>(T t)
            where T : Student//固定了对象
        {
            Console.WriteLine(t);
        }

        public static void Show<T>(T t) where T : new()//约束--表示T类型只接收一个无参的构造函数new T()实例化一个对象
        {
            Console.WriteLine(t);
        }

        /// <summary>
        /// 泛型方法,可以多个Show<T,K>(T t,K k)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        public static void Show1<T>(T t)
        {
            Console.WriteLine(t.ToString());
        }
        #endregion


    }
    public class People
    {
        public int Id { get; set; }
    }
    public class Teacher : People//子类
    {
        public string Name { get; set; }
    }

    #region 协变
    /// <summary>
    /// 协变只能返回结果,不能做参数
    /// </summary>
    /// <typeparam name="T"></typeparam>
    interface IListOut<out T>
    {
        T GetT();
    }

    class ListOut<T> : IListOut<T>
    {
        public T GetT()
        {
            return default(T);//default关键字,如果是值类型默认返回0,是引用类型默认返回null
        }
    }
    #endregion

    #region 逆变
    /// <summary>
    /// in修饰,逆变后,T只能作为当参数  不能做返回值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IListIN<in T>
    {
        //T GetT();//不能使用
        void Show(T t);//与协变相反
    }
    class ListIN<T> : IListIN<T>
    {
        public void Show(T t)
        {
            //throw new NotImplementedException();
        }
    }
    #endregion


    #region 协变+逆变
    public interface IOutInList<in inT, out outT>
    {
        void Show(inT t);
        outT Get();
        outT Do(inT t);

        //out 只能是返回值, in只能是参数
        //void Show1(ouT t);
        //inT Get1();
    }

    public class OutIntList<T1, T2> : IOutInList<T1, T2>
    {
        public T2 Do(T1 t)
        {
            return default(T2);
            //throw new NotImplementedException();
        }

        public T2 Get()//协变作为返回值
        {
            throw new NotImplementedException();
        }

        public void Show(T1 t)//逆变作为参数
        {
            throw new NotImplementedException();
        }
    }
    #endregion

    #region 泛型约束
    public interface IStudent<T>//泛型接口
    {

    }
    public interface IStudent//普通接口
    {
        //没有构造函数
    }
    public class Student//普通类
    {
        //默认有一个无参数的构造
    }
    public class Student2//普通类
    {
        //默认有一个无参数的构造
    }

    public class Student3<T> : Student//继承Student
    {
        //默认有一个无参数的构造
    }
    public class Student4<T> : Student where T : new()//继承Student  where T :new()是约束
    {
        //默认有一个无参数的构造
    }

    /// <summary>
    /// 泛型类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class MyGeneric<T>
    {
        private T t;
        public MyGeneric(T t1)
        {
            this.t = t1;
        }
        public void Show()
        {
            Console.WriteLine(t);
        }
    }
    #endregion
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值