C#复习之泛型 Generic

2021-12-10
3 min read
Featured Image

泛型

  • 广泛的类型: 泛型类, 泛型方法, 泛型集合, 泛型接口, 泛型委托.

  • 泛型的运用主要在 泛型集合.

  • 泛型类的约束: 关键字 where

    • where T: struct
      • 约束 T 为值类型, 因为在 c# 语言中所有的值类型都是用 struct 结构去定义的.
    • where T: class
      • 约束 T 为引用类型
    • where T: new()
      • 约束 T 为含有 public 无参构造函数的类型
      • 基本的值类型有, 引用类型没有
      • 自定义的类是可以的
    • where T:K
      • 约束 T 为 K 的子类
    • where T:IMyInterface
      • 约束 T 必须为 IMyInterface 的实现类
  • 值类型和引用类型的复习

    • 值类型: 整型 + 浮点型 + 字符 + 布尔 + 日期 + 枚举 + 结构
    • 应用类型: 字符串 + 数组 + 类 + 接口 + 委托
/*
 * 1.泛型方法
 * 2.泛型类
 * 3.泛型类中的泛型方法
 * 4.两个参数的泛型类
 * 5.泛型的约束 
*/
using System;

namespace GenericTest
{
    class class1
    {
        // 1. 泛型方法的定义
        public void Show<T>(T t)
        {
            Console.WriteLine("This is {0} and parameter is {1}",typeof(class1).Name, t.GetType().Name);
        }
    }

    //2,4. 泛型类
    class GenericClass<T>
    {
        //声明两个泛型的变量
        T a;
        T b;
        //构造函数
        public GenericClass(T a,T b)
        {
            this.a = a;
            this.b = b;
        }
        //方法输出两个字段的拼接
        public string Combine()
        {
            return this.a.ToString() + this.b.ToString();
        }
        //3. 泛型类中的泛型方法, 注意不用写尖括号
        public void Sum(T a, T b) { }
    }

    //5. 两个参数的泛型类, 并对泛型进行约束
    class GenericClass2<T, K, A, B>
        where T : struct //T 必须为值类型
        where K : class //K 必须为引用类型
        where A : new() //A 必须定义无参 public构造函数
        where B : K //K 必须是 B 的父类
    {     
        T a;
        K b;
        // 泛型类的构造函数
        public GenericClass2(T a, K b)
        {
            this.a = a;
            this.b = b;
        }
    }

    // 主程序
    class Program
    {
        static void Main(string[] args)
        {
            #region 泛型方法
            class1 c1 = new class1();
            // 泛型方法的调用方法.
            c1.Show<int>(100);
            // 此方法也能够输出参数的类型, 证明泛型也能够这样调用.
            c1.Show("ss");
            #endregion

            #region 泛型类
            // 调用构造函数需要指定参数类型.
            GenericClass<int> g1 = new GenericClass<int>(123, 456);
            GenericClass<string> g2 = new GenericClass<string>("aa", "ple");
            string res1 = g1.Combine();
            string res2 = g2.Combine();
            Console.WriteLine(res1); // 输出 123456
            Console.WriteLine(res2); // 输出 123456
            #endregion
        }
    }
}

集合

集合和数组的比较

  • 数组: 长度固定, 有序, 元素类型相同
  • 集合: 长度可变, 有序, 元素类型可以不同. 泛型集合可以规定元素类型.

常用集合的分类

  • 传统集合
    • 有序集合: ArrayList 动态数组, 元素类型可以不相同
    • 键值对集合: HashTable 哈希表, 元素类型可以不相同
  • 泛型集合
    • 有序集合: List, 元素类型必须相同
    • 键值对集合: Dictionary<K,V>, 元素类型必须相同

ArrayList 的操作

  • 创建: ArrayList al = new ArrayList(length)
  • 添加元素: add( object v)
    • 装箱的过程: 值类型存到引用类型的过程
    • 拆箱的过程: 把集合内的元素提取出来赋值(比如 int), 有时候需要拆箱: 把引用转值.
    • object 是所有变量类型的顶层父级, 传参可以穿参数的子类, 所以 add 方法可以传任何形式的变量.
    • 当添加的元素数量超过动态数组长度的时候, 长度会自动翻倍.
  • 剩下的懒得写了, 直接写在代码实例里了.
/* 
 * 1.创建
 * 2.添加
 * 3.获取
 * 4.插入
 * 5.插入一组
 * 6.删除
 * 7.排序
 * 8.颠倒
 */
using System;
using System.Collections;

namespace CollectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //1. 创建长度为 10 的动态数组
            ArrayList arrayList = new ArrayList(10);
            //2. 添加一个整型到动态数组, 装箱
            arrayList.Add(100);
            //3. 获取元素, 拆箱 
            int a = Convert.ToInt32(arrayList[0]);
            //4. 在 0 位置上插入一个整型, 后面的元素一次往后移位
            //不能在最后一个元素之后的之后插入, 中间不能有空位
            arrayList.Insert(0, 100);
            //5. 插入一组数据, 两个参数一个是插入节点, 一个是实现了 ICollection 接口的数据类型
            int[] list = { 1, 2, 3, 4 }; //初始化一个数组
            arrayList.InsertRange(3, list);
            //6. 删除元素
            arrayList.Remove(100); //删除 100
            arrayList.RemoveAt(0); //删除 第一个元素
            arrayList.RemoveRange(0, 2); //删除 从 0 开始往后 2 个元素
            //7. 元素排序和颠倒
            arrayList.Sort(); //从小到大 
            arrayList.Reverse();
            //8. 转换成数组, 长度为元素个数 
            Object[] arr = arrayList.ToArray();
            //循环遍历所有元素, count 为元素个数
            for(int i = 0; i < arrayList.Count; i++)
            {
                Console.WriteLine(arrayList[i]);
            }
        }
    }
}


Avatar
Aaron Fan My research interests include machine learning, signal processing, web development and robotics.