Property biasa mengekspos satu nilai per nama. Ketika class menyimpan kumpulan data, misalnya Keranjang yang memuat daftar barang, kita perlu cara membaca dan menulis item satu per satu dengan notasi yang sudah akrab: kurung siku. Indexer menyediakan notasi tersebut. Dengan indexer, pemanggil menulis keranjang[0] pada object class, sama nyamannya dengan mengakses elemen array.
Masalah: Akses Item Koleksi yang Ekspresif #
Class Keranjang menyimpan barang di dalam List<string> yang bersifat privat. Membuka list tersebut ke publik melanggar encapsulation karena kode luar dapat menambah, menghapus, atau mengganti isinya semaunya. Menyediakan method bernama AmbilItem(int index) dan GantiItem(int index, string barang) bisa dilakukan, tetapi notasi pemanggilannya panjang. Indexer memberi akses terkontrol sambil mempertahankan sintaks kurung siku yang ringkas.
Mekanisme Indexer #
Indexer dideklarasikan dengan kata kunci this karena anggota ini tidak memiliki nama sendiri:
- Deklarasi
public string this[int index]mendefinisikan indexer bertipestringyang menerima satu parameterint. - Aksesor
getmenerima parameterindexdan mengembalikan item pada posisi tersebut; aksesorsetmengganti item pada posisi itu denganvalue. - Notasi pemanggilan sama seperti array:
keranjang[0]memanggil aksesorget, dankeranjang[1] = "..."memanggil aksesorset. - Indexer dapat dideklarasikan lebih dari satu pada class yang sama selama daftar parameternya berbeda, misalnya versi
intdan versistring.
Contoh: Indexer pada Class Keranjang #
public class Keranjang
{
private List<string> barang = new List<string>
{
"Beras", "Minyak Goreng", "Gula"
};
public string this[int index]
{
get { return barang[index]; }
set { barang[index] = value; }
}
public int JumlahItem
{
get { return barang.Count; }
}
}
Keranjang keranjang = new Keranjang();
Console.WriteLine($"Item pertama: {keranjang[0]}");
keranjang[1] = "Minyak Kelapa";
for (int i = 0; i < keranjang.JumlahItem; i++)
{
Console.WriteLine($"Item {i}: {keranjang[i]}");
}
try
{
Console.WriteLine(keranjang[5]);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine($"Index tidak valid: {e.Message}");
}Output yang Dihasilkan:
Item pertama: Beras
Item 0: Beras
Item 1: Minyak Kelapa
Item 2: Gula
Index tidak valid: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')Mari kita bedah baris demi baris:
private List<string> barang = ...: koleksi asli tetap privat; satu-satunya akses dari luar adalah indexer dan propertyJumlahItem.public string this[int index]: deklarasi indexer; katathismenggantikan nama anggota, dan parameterindexmenjadi isi kurung siku saat pemanggilan.keranjang[0]: pembacaan memanggil aksesorget, yang meneruskanindexkebarang[index]milik list.keranjang[1] = "Minyak Kelapa";: penugasan memanggil aksesorsetdenganindexbernilai1danvalueberisi"Minyak Kelapa", sehingga item pada posisi itu terganti.keranjang[5]di dalam bloktry: index5berada di luar isi list, aksesorgetmeneruskan permintaan ke list, dan list melemparArgumentOutOfRangeExceptionyang ditangkap blokcatch.