泛型方法 (C# 程式設計手冊)

泛型方法是使用型別參數宣告的方法,如下所示:

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

下列程式碼範例示範一種方法,使用型別引數的 int呼叫方法:

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

您也可以省略型別引數,編譯器會推斷它。 以下對 Swap 的呼叫,相當於先前的呼叫:

Swap(ref a, ref b);

相同的型別推斷規則適用於靜態方法和執行個體方法。 編譯器可以根據您傳入的方法引數推斷型別參數,但無法只從條件約束或傳回值推斷型別參數。 因此,型別推斷對沒有參數的方法不起作用。 編譯時期先出現型別推斷,編譯器才嘗試解析多載的方法簽章。 編譯器會將型別推斷邏輯套用到所有共用相同名稱的泛型方法。 在多載解析步驟中,編譯器只包含型別推斷已成功的那些泛型方法。

在泛型類別中,非泛型方法可以存取類別層級類型的參數,如下所示:

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

如果您定義的泛型方法接受與包含類別相同的型別參數,編譯器會產生警告 CS0693,因為在方法範圍內,為內部 T 提供的引數會隱藏為外部 T 提供的引數。 在類別具現化後,如果您需要以不是提供的型別引數來彈性呼叫泛型類別方法,請考慮為方法的型別參數提供另一個識別碼,如下列範例中的 GenericList2<T> 所示。

class GenericList<T>
{
    // CS0693.
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    // No warning.
    void SampleMethod<U>() { }
}

使用條件約束,在方法中的型別參數上啟用更多特定作業。 本版的 Swap<T> 現在名為 SwapIfGreater<T>,只能搭配實作 IComparable<T> 的型別引數一起使用。

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
    T temp;
    if (lhs.CompareTo(rhs) > 0)
    {
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}

泛型方法可以多載到數個型別參數上。 例如,下列方法可以全都位於相同的類別中:

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

您也可以使用 type 參數作為方法的傳回型別。 下列程式代碼範例顯示傳回 型 T別數位式的方法:

T[] Swap<T>(T a, T b)
{
    return [b, a];
}

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。

另請參閱