Petugas gudang sering perlu menukar isi dua variabel: stok gudang dengan stok toko, atau nama penerima pengiriman pertama dengan nama kedua. Versi non-generik memaksa kita menulis TukarInt, TukarString, dan overload lain untuk setiap tipe. Generic method menghapus pengulangan itu dengan menempatkan type parameter pada deklarasi method, bukan pada class, sehingga satu method melayani semua tipe yang memenuhi syaratnya.

Mendeklarasikan Generic Method #

Type parameter dinyatakan setelah nama method dan sebelum daftar parameter. Seluruh badan method kemudian memperlakukan T sebagai tipe yang utuh:

csharp
public static class UtilitasGudang
{
    public static void Tukar<T>(ref T a, ref T b)
    {
        T sementara = a;
        a = b;
        b = sementara;
    }
}

int stokGudang = 12;
int stokToko = 5;
UtilitasGudang.Tukar(ref stokGudang, ref stokToko);
Console.WriteLine($"Gudang: {stokGudang}, Toko: {stokToko}");

Output yang Dihasilkan:

text
Gudang: 5, Toko: 12

Mari kita bedah baris demi baris:

  1. public static void Tukar<T>(...): Tanda <T> setelah nama method menyatakan type parameter milik method; class UtilitasGudang sendiri tidak generik.
  2. ref T a, ref T b: Kedua parameter bertipe T dan dilewatkan dengan ref, sehingga penugasan di dalam method mengubah variabel milik pemanggil.
  3. T sementara = a;: Variabel penampung sementara dibuat dengan tipe yang sama dengan T, tanpa cast maupun boxing.
  4. UtilitasGudang.Tukar(ref stokGudang, ref stokToko): Pemanggil tidak menulis tipe apa pun; compiler menyimpulkan T adalah int dari kedua argumen (mekanisme ini dibedah pada bab Generic Type Inference).

Menentukan Type Argument Secara Eksplisit #

Kita juga boleh menuliskan type argument secara langsung pada pemanggilan. Bentuk ini berguna ketika kita ingin menegaskan tipe yang dipilih:

csharp
string namaPertama = "Budi";
string namaKedua = "Siti";
UtilitasGudang.Tukar<string>(ref namaPertama, ref namaKedua);
Console.WriteLine($"Pertama: {namaPertama}, Kedua: {namaKedua}");

Output yang Dihasilkan:

text
Pertama: Siti, Kedua: Budi

Pada panggilan kedua ini, compiler memeriksa kecocokan namaPertama dan namaKedua dengan type argument <string> yang kita tulis. Jika kedua argumen bertipe berbeda, compiler menolak pemanggilan tersebut sejak saat kompilasi. Bentuk eksplisit juga membantu pembaca kode: maksud method langsung terlihat tanpa perlu menelusuri tipe argumennya.

Satu method Tukar<T> kini menggantikan seluruh overload per tipe, dan setiap pemanggilan tetap diperiksa tipe oleh compiler.