C#笔记之泛型

泛型是C#中应用极为广泛的一种语法,本篇文章将详细介绍泛型的定义、使用、性能等。

一、什么是泛型

      首先需要记住的是,泛型是.NET 2.0推出的语法,这样的话,泛型基本可以用于所有程序的开发,而不需要担心客户终端或者服务器上不支持的版本。

      泛型将数据类型参数化,即数据类型作为一个参数来使用,等到运行时,根据不同的情况,为这个特殊的参数赋值。

二、为什么用泛型

      我们现在模拟一个应用场景:在一个静态类中,有一个静态的字典类型的变量,变量的key、value类型均为string。

/// <summary>
/// 字典缓存类
/// </summary>
public static class DicCache
{
      public static Dictionary<string, string> dicList = new Dictionary<string, string>();
}

      我们需要往这个静态字段中,添加不同的值,但是我们不能保证value的类型均为string。

public void AddDicData()
        {
            DicCache.dicList.Add("1", "第一个值");
            DicCache.dicList.Add("2", 2);
            DicCache.dicList.Add("3", DateTime.Now);
        }

      这个时候,插入第二、三条的时候,就要报错了。

      

 

       vs明确提示,数据类型不匹配。

      上面我们提到,泛型是建数据类型参数化,这个时候,我们能不能将字典类型变量的value的类型,设置成一个参数,通过参数不同,保存不同类型的值?

      改造之后的代码如下:

/// <summary>
/// 字典缓存类
/// </summary>
public static class DicCache<T>//泛型类
{
    public static Dictionary<string, T> dicList = new Dictionary<string, T>();
}

      代码中,在类DicCache后面添加“<T>”,则该类变成了一个泛型类。字典变量中,value的类型变成了“T”,则value的数据类型成为了一个可变的值。该类新的调用方法也变成了下面的样子。

 

       调用该类的时候,在类名后,已“<>”包含实际的数据类型,提交给该类,则添加数据的时候,不报错了。

三、其它泛型的用法

       泛型不仅包含泛型类,还包含泛型参数、泛型变量、泛型接口、泛型委托等。

    /// <summary>
    /// 泛型的各种类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="S"></typeparam>
    public class GenericityType<T, S>//包含多个泛型参数的类
    {
        public T TData;//泛型变量

        public delegate void SayHello<S>(S s);//泛型委托
    }

    /// <summary>
    /// 泛型接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IGenericityType<T>//泛型接口
    {
        string SayHello(T t);//泛型参数

        T RetT();//泛型返回值
    }

四、泛型约束

       泛型约束包含多种类型的约束,一般在比较大的一些项目或者比较严谨的项目中使用较多。

       类约束

    /// <summary>
    /// 类约束,约束T传入的类型必须是Test类型或者是Test的子类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Company<T> where T:Test
    {
 
    }

  接口约束

    /// <summary>
    /// 接口约束,约束T传入的类型必须是ITest类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Company<T> where T:ITest
    {
 
    }

  类型约束

    /// <summary>
    /// 类型约束,约束T传入的必须是class类型的类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Company<T> where T: class
    {
 
    }

  多重约束

    /// <summary>
    /// 多重约束,约束T传入的必须是class类型的类型或者是ITest接口或者是int类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Company<T> where T: class,ITest,int
    {
 
    }

五、泛型的原理

       泛型是运用了延迟的设计思想,即在声明和编辑的时候,用一个占位符代替了数据类型,等到程序运行的时候,将占位符编译为传入的数据类型。延迟思想在实际项目中很受欢迎,我们再以后的笔记中体现。

六、泛型的性能

  泛型在性能方面,是优于固定类型的,这个大家有兴趣,可以自己做个for循环测试。

七、泛型的应用--缓存

  静态修饰符:static,被定义为静态的类,不管程序经过怎么样的运行,其在内存中,只存在一个,根据这个特性,我们可以自己做一个本地的缓存。

    /// <summary>
    /// 字典缓存类
    /// </summary>
    public static class DicCache<T>//泛型类
    {
        private static Dictionary<string, T> dicList = new Dictionary<string, T>();

        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string AddDic(string key, T value)
        {
            if (Exsits(key))
            {
                return "缓存数据已存在";
            }
            else
            {
                dicList.Add(key, value);
                return "成功";
            }
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T GetDic(string key)
        {
            return (T)dicList[key];
        }

        /// <summary>
        /// 删除指定缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool DeleteDic(string key)
        {
            return dicList.Remove(key);
        }

        /// <summary>
        /// 删除所有缓存
        /// </summary>
        public static void DeleteAllDic()
        {
            dicList.Clear();
        }

        /// <summary>
        /// 判断缓存是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Exsits(string key)
        {
            return dicList.ContainsKey(key);
        }
    }

  缓存是一个大标题,系统优化中,缓存是不可缺少的一个环节,后期的笔记中,也会不断体现患者的其它实现方式。

八、特别说明

  本人是一个马上过期的码农,现在想把自己之前用到的一些知识点总结记录一下,有错误或遗漏,请大神指正。

posted @ 2021-07-19 16:14  资深码农0311  阅读(71)  评论(0编辑  收藏  举报