zoukankan      html  css  js  c++  java
  • 泛型基础

      泛型是CLR和编程语言提供的一种特殊机制,它可以支持代码重用。

      我们在编写程序的时候,经常会遇到两个模块的功能非常相似,只是一个处理int类型的数据一个处理string数据,或者其他自定义的数据类型,而c#中的类型是强类型,我们不得不写多个方法分别处理不同的带护具类型,那么有没有一种办法,在方法中传入通用的数据类型,这样只要实现一个方法就可以了?泛型这种机制就是为了就是这个问题的解决方案之一。

    例如我们要实现一个栈:

     public class Stack
        {
            private List<Int32> m_item;
            public Int32 Pop(){
                if (m_item.Count < 1)
                {
                    throw new NullReferenceException();
                }
                else
                {
                    Int32 popValue = m_item[m_item.Count - 1];
                    m_item.RemoveAt(m_item.Count - 1);
                    return popValue;
                }
            }
            public void Push(Int32 item)
            {
                m_item.Add(item);
            }
            public Stack(Int32 i)
            {
                this.m_item = new List<Int32>();
            }
        }
    

       上面的代码运行没有任何问题,但是他只能处理Int类型的栈结构,如果需要一个浮点数或者字符串型的栈就需要重新实现一遍栈。我们雍凡星来重新实现一次栈如下:

    public class Stack<T>
        {
            private List<T> m_item;
            public T Pop()
            {
                if (m_item.Count < 1)
                {
                    throw new NullReferenceException();
                }
                else
                {
                    T popValue = m_item[m_item.Count - 1];
                    m_item.RemoveAt(m_item.Count - 1);
                    return popValue;
                }
            }
            public void Push(T item)
            {
                m_item.Add(item);
            }
            public Stack()
            {
                this.m_item = new List<T>();
            }
        }
    

     以上,T只是一个占位符,它可以是任意的值类型或者引用类型,枚举类型除外,这样一个方法就可以支持int类型的栈结构也可以支持double类型的栈;调用如下:

     Stack<Int32> stack = new Stack<Int32>();
     stack.Push(1);
     stack.Push(100);
     Int32 value = stack.Pop();
    

     泛型的好处:

    • 它是类型安全的。实例化了int类型的栈,就不能处理string类型的数据,其他数据类型也一样。
    • 无需装箱和折箱。这个类在实例化时,按照所传入的数据类型生成本地代码,本地代码数据类型已确定,所以无需装箱和折箱。
    • 无需类型转换。

      泛型类在编译时,先生成中间代码IL,通用类型T只是一个占位符。在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。按照这个原理,我们可以这样认为:

      泛型类的不同的封闭类是分别不同的数据类型。

      例:Stack<int>和Stack<string>是两个完全没有任何关系的类,你可以把他看成类A和类B,这个解释对泛型类的静态成员的理解有很大帮助。

      一些典型的泛型类

      Net框架类库中,System.Collections.Generic和System.Collections.ObjectModel命名空间中,分别定义了大量的泛型类和泛型接口,这些泛型类多为集合类,因为泛型最大的应用正体现于再集合中对于不同类型对象的管理。

    下表列出了,.Net框架中常用的泛型类和泛型接口:

    泛型类

    说明

    List<T>

    对应于ArrayList集合类,可以动态调整集合容量,通过索引方式访问对象,支持排序、搜索和其他常见操作。

    SortedList<TKey,TValue>

    对应于SortedList集合类,表示Key/Value对集合,类似于SortedDictionary<TKey,TValue>集合类,而SortedList在内存上更有优势。

    Queue<T>

    对应于Queue集合类,是一种先进先出的集合类,常应用于顺序存储处理。

    Stack<T>

    对应于Stack集合类,是一种后进先出的集合类。

    Collection<T>

    对应于CollectionBase集合类,是用于自定义泛型集合的基类,提供了受保护的方法来实现定制泛型集合的行为Collection<T>的实例是可修改的。

    Dictionary<TKey,TValue>

    对应于Hashtable集合类,表示Key/Value对的集合类,Key必须是唯一的,其元素类型既不是Key的类型,也不是Value的类型,而是KeyValuePair类型。

      

  • 相关阅读:
    简单工厂笔记
    P3369 【模板】普通平衡树 Treap树堆学习笔记
    tp5阿里云短信验证码
    centos 安装php
    tp6.0.2开启多应用模式
    linux navicat最新版过期
    git commit之后 取消commit
    服务器重置之后ssh root@报错
    git pull push 每次都需要输入账号和密码
    跨域问题 php
  • 原文地址:https://www.cnblogs.com/mohanchen/p/9350204.html
Copyright © 2011-2022 走看看