zoukankan      html  css  js  c++  java
  • C# 集合与泛型

    一.古典集合方式

      在C#2.0的时候集合主要通过两种方式实现:

      1.使用ArrayList实现

      新建ArrayList,然后将所有对象放入该数组中,简单直接,但缺点是该数组什么类型的元素都能接收,在实际使用时对编程人员产生很多困扰。

      2.使用自定义集合类

      比较常见的做法是从CollectionBase抽象类继承一个自定义类,通过对IList对象进行封装实现强类型集合。这种方式要求为每种集合类型写一个相应的自定义类,工作量较大。

    而泛型集合的出现较好的解决了上述问题,只需一行代码便能创建指定类型的集合。

    二.泛型简介

      泛型是C# 2.0中的新增元素(C++中称为模板),主要用于解决一系列类似的问题。这种机制允许将类名作为参数传递给泛型类型,并生成相应的对象。

      将泛型(包括类、接口、方法、委托等)看作模板可能更好理解,模板中的变体部分将被作为参数传进来的类名称所代替,从而得到一个新的类型定义。

      泛型是一个比较大的话题,在此不作详细解析,有兴趣者可以查阅相关资料。

    三.泛型集合的优点

      1.自动封/拆箱

      2.代码简洁

      3.针对对象明确

    四.泛型发展

      a.在最初的时候C#2.0版本,对ArrayList的应用很多,但该类集合什么类型的元素都能接收,有很大缺点。如下:

     ArrayList data = new ArrayList();
                data.Add("alphabet");//string 类型
                data.Add(111);//int 类型
                data.Add(5.5);//double 类型
                data.Add(true);//bool类型

      b.另一种是使用自定义集合方式

      新建个类Person

      

     class Person
        {
            public int Age;
            public string Name;
            public Person() { }
            public Person(int age, string name) {
                Age = age;
                Name = name;
            }
            public override string ToString()
            {
                return string.Format("Name:{0},Age:{1}",Name,Age);
            }
        }

      然后建立Rerson的集合

      

     class PersonCollection:IEnumerable
        {
            private ArrayList arPeople = new ArrayList();
            
            public PersonCollection() { }
    
            public Person GetPerson(int s)
            {
                return (Person)arPeople[s];
            }
    
            public void AddPerson(Person p) {
                arPeople.Add(p);
            }
    
            public void ClearPerson() {
                arPeople.Clear();
            }
    
            public int Count {
                get { return arPeople.Count; }
            }
    
            IEnumerator IEnumerable.GetEnumerator() {
                return arPeople.GetEnumerator();
            }
        }

      这个就是自定义集合,只接受Person类型的数据。

    使用时如下:

      

                PersonCollection mypeople = new PersonCollection();
                mypeople.AddPerson(new Person(21, "Tom"));
                mypeople.AddPerson(new Person(22, "Bom"));
                mypeople.AddPerson(new Person(23, "Com"));
                mypeople.AddPerson(new Person(24, "Dom"));
                mypeople.AddPerson(new Person(25, "Wom"));
    
                mypeople.AddPerson(int 20);//添加其他类型的数据都会报错

      该自定义集合实现了编程人员所需要的要求,但编制过程中代码麻烦,难于管理,应用起来非常麻烦。

    c.泛型使用

      泛型主要利用System.Collections.Generic命名空间下面的List泛型类创建集合,语法如下:

      List<T> ListOfT = new List<T>();

      其中的"T"就是所要使用的类型,既可以是简单类型,如string、int,也可以是用户自定义类型。

      举个例子:

                List<Person> myPerson = new List<Person>();
                myPerson.Add(new Person(21, "Tim"));
                myPerson.Add(new Person(22, "Bim"));
                myPerson.Add(new Person(23, "Cim"));
                myPerson.Add(new Person(24, "Dim"));
                myPerson.Add(new Person(25, "Wim"));

      该集合myPerson只接受Person类型的数据。可以看到,泛型集合大大简化了集合的实现代码,通过它,可以轻松创建指定类型的集合。

    五.泛型方法

      这个没有什么好说的,和泛型集合差不多含义。

      

         static void Swap<T>(ref  T a,ref T b) {
                T temp;
                temp = a;
                a = b;
                b = temp;
            }

    六.泛型类

      

     class GenericityPerson<T>
        {
    
        }

    在使用时为了构建更类型安全的容器,会对传入类型参数进行强制约束

    泛型约束    
     where T struct 该类型参数<T>中必须在其继承链中必须有System.ValueType值类型
     where T class <T>必须是引用类型
     where T new() <T>必须有一个默认的函数,注意在有多个约束的类型上,此约束必须列在末尾
     where T NameOfBaseClass <T>派生于必须NameOfBaseClass指定的类
     where T NameOfInterface <T>派生于必须NameOfInterface指定的接口,多接口必须用逗号隔开

    实例如下

     //GenericityPerson派生自Object,包含的子项必须有一个默认的构造函数
        class GenericityPerson<T> where T:new()
        {
    
        }
        //GenericityPerson派生自Object,包含的子项必须实现IDrawable接口并有默认的构造函数    
        class GenericityPerson<T> where T :class,IDrawable, new()
        {
    
        }
        //GenericityPerson派生自Person并实现了IDrawable接口,同时包含的子项必须是结构
        class GenericityPerson<T> where T : Person,IDrawable where T:struct
        {
    
        }
        //<K>必须有一个默认的构造函数,同时<T>必须实现泛型IComparable接口
        class GenericityPerson<K,T> where K : new()
            where  T:IComparable<T>
        {
    
        }

    七.示例下载

  • 相关阅读:
    C#基于引用创建单链表
    锻炼自己的思维模式
    [数据结构]C#基于数组实现泛型顺序表
    DEV Express
    [LeetCode] Combinations (bfs bad、dfs 递归 accept)
    [LeetCode] Wildcard Matching
    [LeetCode] Remove Duplicates from Sorted List II
    [LeetCode] Partition List
    [LeetCode] Scramble String(树的问题最易用递归)
    [LeetCode] Decode Ways(DP)
  • 原文地址:https://www.cnblogs.com/Khan-Sadas/p/5213123.html
Copyright © 2011-2022 走看看