• .NET知识梳理——1.泛型Generic


    1. 泛型Generic

    1.1        引入泛型:延迟声明

    泛型方法声明时,并未写死类型,在调用的时候再指定类型。

    延迟声明:推迟一切可以推迟的。

    1.2        如何声明和使用泛型

    泛型方法:方法名称后面加上尖括号,里面是类型参数

    类型参数实际上就是一个类型T声明,方法就可以用这个类型T了。

    如下所示:

    public static void Show<T>(T t)

            {

                Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

            }

    1.3        泛型的好处和原理

    泛型方法性能跟普通方法一致,泛型声明方法时,并未写死类型,T是什么类型,只有在调用的时候才知道,一个方法能满足不同类型。

    1.4        泛型类、泛型方法、泛型接口、泛型委托

    1.4.1  泛型类型

    一个类满足不同类型的需求

    具体如下:

    public class BaseModel

        {

            public int Id { get; set; }

        }

        public class GenericClass<T>

            where T:BaseModel//为泛型基类约束

        {

     

        }

    1.4.2  泛型方法

    一个方法满足不同类型的需求

    具体如下:

    public static void Show<T>(T t)

            {

                Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

            }

    1.4.3  泛型接口

    一个接口满足不同类型的需求

       //泛型接口

        public interface IGenericInterface<T>

        {

            public void  SayHi(T t);

    }

    1.4.4  泛型委托

    一个委托满足不同类型的需求

    public delegate void Do<T>(T t);

    1.5        泛型约束

    没有约束,泛型会很局限。主要有5中泛型的约束。如下:

    1.5.1  基类约束

    Where T:BaseModel

    可以把BaseModel当作基类

    只有该类型的对象或从该类型派生出的对象,可被用作类型参数。(密封类约束的不行,因为没有意义。)

    //基类

        public class BaseModel

        {

            public int Id { get; set; }

        }

        //泛型类

        public class GenericClass<T>

            where T:BaseModel//为泛型基类约束

        {

     

    }

    调用:

      GenericConstraint.Show<BeiJing>(new BeiJing());

    1.5.2  引用类型约束

    //引用类型约束

            public static T Get<T>() where T:class

            {

                return default(T);//default是关键字,根据类型T返回对应的默认值

            }

    调用:

    GenericConstraint.Get<Person>(new Person());

    1.5.3  值类型约束

      //值类型约束

            Public static D GetD<D>() where D:struct

            {

                return default(D);

            }

    调用:

    GenericConstraint.GetD<int>(116);

    1.5.4  无参数构造函数

    //无参数构造函数约束

            Public static S GetS<S>()

                where S: new()//无餐构造函数约束

            {     

                return new S();

            }

    调用:

    GenericConstraint.GetS<Chinese>();

    1.5.5  接口约束

    //接口约束

            public static void Show2<T>(T t) where T : ISports

            {

                t.Basketball();

            }

    调用:

    GenericConstraint.Show2<USA>(new USA());

    1.6        协变、逆变

    所谓协变、逆变都是跟泛型有关的(多用在接口)。

    1.6.1  协变

    修饰返回值

    让右边用子类,让泛型用起来更方便(子类转父类)

    Out修饰,协变后只能是返回结果,不能做参数

    IEnumerable<Bird> birdList=new List<Sparrow>();

      //out 协变,只能是返回结果(子类转父类)

        public interface ICustomerListOut<out T>

        {

            T Get();

        }

     

        public class CustomerListOut<T>:ICustomerListOut<T>

        {

            public T Get()

            {

                return default(T);

            }

    }

    ICustomerListOut<Bird> list2 = new CustomerListOut<Sparrow>();

                Func<Bird> func = new Func<Sparrow>(() => null);

                IEnumerable<Bird> list3 = new List<Sparrow>();

    1.6.2  逆变

    修饰传入参数

    让右边可以用父类,让泛型用起来更方便(父类转子类)

    In修饰,逆变后只能当作参数

    //in 逆变 只能是输入参数(父类转子类)

        public interface ICustomerListIn<in T>

        {

            void Show(T t);

        }

        public class CustomerListIn<T>:ICustomerListIn<T>

        {

            public void Show(T t)

            {

                Console.WriteLine(t.GetType().Name);

            }

    }

      //逆变

                ICustomerListIn<Sparrow> list1 = new CustomerListIn<Bird>();

                Action<Sparrow> action = new Action<Bird>((i) => { });

    public interface IMyList<in inT,out outT>

        {

            void Show(inT t);

            outT Get();

            outT Do(inT t);

        }

     

        public class MyList<T, T1> : IMyList<T, T1>

        {

            public void Show(T t)

            {

                Console.WriteLine(t.GetType().Name);

            }

     

            public T1 Get()

            {

                Console.WriteLine(typeof(T1).Name);

                return default(T1);

            }

     

            public T1 Do(T t)

            {

                Console.WriteLine(t.GetType().Name);

                Console.WriteLine(typeof(T1).Name);

                return default(T1);

            }

        }

       IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>();

        IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>();//协变

        IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>();//逆变

    IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>();//逆变+协变

    1.7        泛型缓存

    泛型缓存,每个类型都会生成一个不同的副本(适合不同类型需要缓存一份数据的场景)

      public class GenericCache<T>

        {

            private static string _TypeTime = "";

            static GenericCache()

            {

                Console.WriteLine("This is GenericCache 静态构造函数");

                _TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";

            }

     

            public static string GetCache()

            {

                return _TypeTime;

            }

    }

    /// <summary>

        /// 字典缓存:静态属性常驻内存

        /// </summary>

        public class DictionaryCache

        {

            private static Dictionary<Type, string> _TypeTimeDictionary = null;

            static DictionaryCache()

            {

                Console.WriteLine("This is DictionaryCache 静态构造函数");

                _TypeTimeDictionary = new Dictionary<Type, string>();

            }

            public static string GetCache<T>()

            {

                Type type = typeof(Type);

                if (!_TypeTimeDictionary.ContainsKey(type))

                    _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH mm:ss")}";

                return _TypeTimeDictionary[type];

            }

        }

  • 相关阅读:
    GIT提交修改的项目到远程仓库
    MySQL基础知识总结
    IDEA集成码云gitee
    SpringBoot整合ueditor编辑器
    word2010中统一调整表格格式
    Afinal简介和使用方法
    Java 8 安装——使用华为镜像
    微信小程序调用第三方组件
    webpack-dev-server first try
    性能测试应用领域
  • 原文地址:https://www.cnblogs.com/Olive116/p/12334767.html
Copyright © 2020-2023  润新知