C#快速入門教程(21)—— 泛型

曹化宇發表於2018-11-02

泛型(generic),簡單的說就是使用相同的程式碼操作不同的資料型別,簡化程式碼的編寫工作;相關的概念包括泛型方法、泛型類、泛型介面、泛型約束等。

泛型方法

關於泛型方法,我比較喜歡的例子就是交換兩個變數的值。先看一個交換int型別資料的方法,如下面的程式碼。

using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 99;
            Swap(ref a, ref b);
            Console.WriteLine("a={0}, b={1}", a, b);
        }
        //
        static void Swap(ref int x,ref int y)
        {
            int tmp = x;
            x = y;
            y = tmp;
        }
    }
}

程式碼執行結果如下圖所示。

enter image description here

交換兩個資料的操作是很常見的操作,如果需要對每個型別都寫一個過載方法,那工作量就太大了,而泛型就是來解決這類問題的;下面的程式碼,我們使用一個泛型方法來解決兩個值交換的問題。

using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 99;
            Swap(ref a, ref b);
            Console.WriteLine("a={0}, b={1}", a, b);
        }
        //
        static void Swap<T>(ref T x,ref T y)
        {
            T tmp = x;
            x = y;
            y = tmp;
        }
    }
}

程式碼執行結果與上圖一致,關鍵在於,使用這裡的Swap()方法可以交換任何型別的資料,而不只是int型別,大家可定義不同型別的資料進行測試。

此處定義的Swap()方法就是一個泛型方法,與普通方法的不同之處在於,方法名的後面使用一對尖括號宣告瞭一個型別識別符號T(type),這是一個習慣用法,實際應用中還可以宣告多個型別標識;定義了型別標識之後,就可以在方法的引數、方法體和返回值中使用,如下面的程式碼。

static T Test<T>(T x)
{
        T y = x;
        return y;
}

泛型類

定義泛型類時,需要在類名後面使用一對尖括號宣告型別標識,然後,在類中就可以使用這些型別標識了,如下面的程式碼。

namespace ConsoleTest
{
    public class CDictItem<K,V>
    {
        public K Key { get; set; }
        public V Value { get; set; }
    }
}

本例中,我們定義了CDictItem類,並定義了兩個型別標識,K和V,分別表示字典專案的鍵(key)和值(value);下面的程式碼演示瞭如何使用這個泛型類。

static void Main(string[] args)
{
        CDictItem<string, string> item = new CDictItem<string, string>();
        item.Key = "Mars";
        item.Value = "火星";
        Console.WriteLine("{0}: {1}", item.Key, item.Value);
}

程式碼執行結果如下圖所示。

enter image description here

泛型介面

介面的功能就是定義演算法和功能標準,使用了泛型就可以通過一個介面完成更多資料型別的相同操作。需要注意的是,實現泛型介面時應使用泛型類,如下面的程式碼演示了一個簡單的泛型介面實現。

//
public interface  IG1<T>
{
    T Data { get; set; }
    void ShowData(T d);
}
//
public class CG1<T> : IG1<T>
{
    public T Data { get; set; }
    public void ShowData(T d)
    {
        Console.WriteLine(d == null ? "NULL" : d.ToString());
    }
}

泛型約束

泛型約束是指,在使用泛型型別時,其資料型別可以進行限制,如操作的資料型別必須是實現了某介面的型別,如下面的程式碼。

public class CCls1<T> where T : I1
{
    public T Obj { get; set; }
}

這裡的CCls1類中的T型別必須是實現了I1介面的型別。

小結

從以上內容中可以看到,泛型就是定義一個演算法或功能,在真正使用時才指定具體的資料型別,這樣的好處就是提高開發效率,而且,由於程式碼執行時會繫結具體的型別,所以也不會影響執行效率;這樣一來,泛型的強大之處就一目瞭然了。

在.NET Framework類庫中定義了大量的泛型資源,在學習和工作中可以參考MSDN文件使用。

CHY軟體小屋原創作品!

相關文章