泛型

咸鱼翻身?發表於2024-03-07

簡介

C# 中的泛型是一種強大的特性,允許你編寫可重用的程式碼,而不必為不同的資料型別編寫多個版本。透過泛型,你可以建立類、方法和介面,以便它們可以在編譯時指定具體的資料型別。這使得程式碼更加靈活、型別安全,並且可以提高效能。

案例

泛型允許我們編寫程式碼時指定型別引數,以便在執行時使用不同的實際型別。假設我們有一個簡單的需求:實現一個陣列的查詢最大值功能。我們可以比較使用泛型前後的實現

不使用泛型

public class NonGenericMaxFinder
{
    public int FindMaxInt(int[] array)
    {
        if (array == null || array.Length == 0)
            throw new ArgumentException("Array cannot be null or empty.");

        int max = array[0];
        foreach (int num in array)
        {
            if (num > max)
                max = num;
        }
        return max;
    }

    public double FindMaxDouble(double[] array)
    {
        if (array == null || array.Length == 0)
            throw new ArgumentException("Array cannot be null or empty.");

        double max = array[0];
        foreach (double num in array)
        {
            if (num > max)
                max = num;
        }
        return max;
    }

    // More methods for other types if needed...
}

使用泛型

public class GenericMaxFinder<T> where T : IComparable<T>
{
    public T FindMax(T[] array)
    {
        if (array == null || array.Length == 0)
            throw new ArgumentException("Array cannot be null or empty.");

        T max = array[0];
        foreach (T item in array)
        {
            if (item.CompareTo(max) > 0)
                max = item;
        }
        return max;
    }
}

在這個例子中,GenericMaxClass<T>是一個泛型類,其中的T是型別引數。在例項化時,您可以指定T的具體型別。使用泛型後,我們只需要一個通用的方法來處理各種型別的陣列,而不需要為每種型別編寫單獨的方法,這使得程式碼更加簡潔。

泛型約束

泛型約束允許對泛型型別引數進行更嚴格的限制。例如,可以使用where子句來指定型別引數必須是特定型別、必須實現特定介面或必須具有無參建構函式等。以下是一個示例:

public class GenericClass<T> where T : IComparable
{
    // 泛型類體
}

在這個示例中,T必須實現IComparable介面。還可以使用where T : struct來指定T必須是值型別。

泛型方法

除了泛型類之外,C#還支援泛型方法。這使得可以在方法級別使用泛型。以下是一個示例:

public class GenericMethodExample
{
    public T Max<T>(T first, T second) where T : IComparable
    {
        return first.CompareTo(second) >= 0 ? first : second;
    }
}

在這個示例中,Max方法是一個泛型方法,它接受兩個引數並返回較大的那個。T被約束為實現IComparable介面的型別。

泛型委託

C#中的委託也可以是泛型的,這使得可以定義可重用的委託型別,而不必為每種型別都定義一個新的委託型別。以下是一個示例:

public delegate T Transformer<T>(T arg);

這裡,Transformer<T>是一個泛型委託,它接受一個型別為T的引數並返回相同型別的結果。

三大特性

1. 型別安全性(Type Safety)

泛型提供了在編譯時進行型別檢查的機制,這意味著可以在編譯時捕獲型別不匹配的錯誤。使用泛型,可以在編寫程式碼時指定型別引數,並且編譯器會確保在使用這些引數時型別的一致性。這有助於防止在執行時出現型別轉換錯誤或無效操作,提高了程式碼的可靠性和安全性。

2. 程式碼重用性(Code Reusability)

泛型允許編寫可重用的通用程式碼,這意味著可以編寫一次程式碼,然後在不同的資料型別上重複使用它。透過泛型,可以建立適用於多種型別的類、方法、介面和委託等元件,而不必針對每種型別都編寫單獨的程式碼。這樣可以減少程式碼重複,提高了程式碼的可維護性和可擴充套件性。

3. 效能最佳化(Performance Optimization)

泛型在一定程度上可以提高程式碼的效能。由於泛型在編譯時生成特定型別的程式碼,避免了裝箱(boxing)和拆箱(unboxing)操作,從而減少了在執行時的效能開銷。此外,泛型還可以減少由於型別轉換和執行時型別檢查而產生的額外開銷。因此,泛型在某些情況下可以提高程式碼的執行效率。

相關文章