C#泛型

一、泛型概念

C# 語言和公共語言運行時 (CLR) 在 2.0 版本中添加了泛型。泛型將類型參數的概念引入 .NET Framework,這樣就可以設計具有相同特徵的類和方法:在客戶端代碼聲明並初始化這些類和方法之前,這些類和方法會延遲指定一個或多個類型(使用佔位符~3:數字代表類型參數個數)

二、泛型的作用

使用泛型類型可以最大限度地重用代碼保護類型安全性以及提高性能。泛型最常見的用途是創建集合類 List< int>。

1.泛型分類:

泛型接口、泛型類泛型方法、泛型事件和泛型委託

2.泛型的好處

(1)增加類型的安全性
(2)提高代碼的重用

三、泛型的使用

(一)泛型類

1.創建泛型類

在這裏插入圖片描述

2.案例:

//泛型類
    class MyList<T>
    {
        T[] stack; //聲明數組
        int size; //數組長度
        int stacPoint; //當前位置指針(索引)
        public MyList(int length)
        {
            this.size = length;
            stack = new T[size];
            stacPoint = -1;
        }
        // 入棧
        public void Add(T item)
        {
            if (stacPoint>=size) //如果超過數組長度
            {
                Console.WriteLine("集合已滿");
            }
            else
            {
                stacPoint++;
                stack[stacPoint] = item;
            }
        }
        // 出棧
        public T Pop()
        {
            T data = stack[stacPoint];
            stacPoint--;
            return data;
        }
    }
// 主運行窗口
		static void Main(string[] args)
        {
            //實例化泛型類
            MyList<int> list = new MyList<int>(6);
            //入棧 
            list.Add(1);
            list.Add(2);
            list.Add(3);
            list.Add(4);
            list.Add(5);
            //出棧
            Console.WriteLine(list.Pop()); // 5
            Console.WriteLine(list.Pop()); // 4
            Console.WriteLine(list.Pop()); // 3
            Console.WriteLine(list.Pop());// 2
            Console.WriteLine(list.Pop());// 1
            Console.ReadLine();
        }

3.泛型類的規範:

    public class 類名<T> {類成員....}

(1) T:僅代表一個佔位符,用T或者其他字母都行,只要符合C#命名規範都行,但是一般情況用T
(2) T:表示一個通用的數據類型,在使用的時候用實際類型代替
(3)T:泛型類可以在定義中可以包含多個任意類型參數,參數之間使用逗號隔開

    public class 類名<T1,T2,T3,....>{...}

各種類型參數都可以用作成員變量的類型屬性方法等成員的返回類型,以及方法的參數類型
以上泛型類的使用,增加了類型安全,實例化時int類型的約束下是不能添加string類型。無需拆箱操作

4.泛型類型的問題

無法爲泛型類型賦值初始

因爲泛型類型可以理解爲泛指所有的數據類型,而所有的數據類型可分爲:值類型和引用類型,而且不同的數據類型支持的默認值是不一樣的。
注意:
(1) 不能隨便假設泛型類型是某種類型,這種類型也許沒有構造方法,也許是私有的
(2) 解決方案使用default關鍵字,如果defalut中指定的類型最終是引用類型則默認是null,如果是值類型那就給值類型對應的默認值,數值就是0.結構類型要根據具體的成員類型確定是0還是null

(二)泛型方法

案例

		static void Main(string[] args)
        {
            Console.WriteLine(Add<int>(11,12));//23
            Console.WriteLine(Add<double>(11.5,12.5));// 24
            //Console.WriteLine(Add<char>('a','b'));//異常實參不爲值類型 
            Console.ReadLine();
        }
        //泛型方法
        static T Add<T>(T a,T b) where T : struct
        {
            dynamic a1 = a;  // 設置動態類型   根據程序執行動態獲取當前類型
            dynamic b1 = b;
            return a1 + b1;
        }

四、泛型約束

1.泛型約束有哪些

  1. where T : struct 類型參數必須值類型
  2. where T : class 類型參數必須引用類型。 此約束還應用於任何類、接口、委託或數組類型。
  3. where T : unmanaged 類型參數不能是引用類型,並且任何嵌套級別均不能包含任何引用類型成員
  4. where T : new() 類型參數必須具有公共無參數構造函數
  5. where T : <基類名> 類型參數必須是指定的基類或派生自指定的基類
  6. where T : <接口名稱> 類型參數必須是指定的接口或實現指定的接口
  7. where T : U 爲 T 提供的類型參數必須是爲 U 提供的參數或派生自爲 U 提供的參數。

2.案例

 	static void Main(string[] args)
    {
            MyGenericClass<int, Course, Teacher> myGener = new MyGenericClass<int, Course, Teacher>();
            myGener.ProductList = new List<Course>()
            {
                new Course(){CourseName="ASP.NET",Period=6},
                new Course{CourseName="WEB",Period=5}
            };
            Course c = myGener.GetClass(0);
            Console.WriteLine($"{c.CourseName}課程的週期{c.Period}");
            Console.ReadLine();
   }
   //泛型類
   class MyGenericClass<T1, T2, T3>
        where T1:struct //值類型
        where T2:class  //引用類型 (還包含:類,接口,委託,數組)
        where T3:new () //無參數構造函數
    {
        public List<T2> ProductList { get; set; } //聲明以T2集合爲類型的屬性
        public T3 Teachers { get; set; } //聲明以T3爲類型的屬性
        //聲明以T2 爲返回類型、T1類型爲參數,的方法
        public T2 GetClass(T1 num)
        {
            dynamic a = num; //根據T1獲取到a的數據類型
            return ProductList[a]; //返回數組中a索引對應的數據
        }
    }
    //參數類 T2:代表所學的科目類
    class Course 
    {
        /// <summary>
        /// 課程名稱
        /// </summary>
        public string CourseName { get; set; }
        /// <summary>
        /// 學習週期
        /// </summary>
        public int Period { get; set; }

    }
    //參數類 T3:代表老師
    class Teacher
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 授課數量
        /// </summary>
        public int Count { get; set; }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章