Hasil kueri berbentuk IEnumerable<T> memang fleksibel, tetapi banyak bagian aplikasi menuntut bentuk konkret: List<T> untuk API yang menerima daftar, array untuk ukuran tetap, atau Dictionary untuk pencarian cepat. Operator konversi melakukan materialisasi sekaligus mengubah wadahnya.

Materialisasi ke Wadah Baru #

Contoh berikut menyimpan hasil kueri ke tiga wadah berbeda dan menyaring array campuran:

csharp
record Produk(string Nama, string Kategori, int Harga, int Stok);

List<Produk> produk = new()
{
    new Produk("Kopi Gayo", "Minuman", 25000, 40),
    new Produk("Teh Melati", "Minuman", 15000, 60),
    new Produk("Roti Bakar", "Makanan", 12000, 25),
    new Produk("Susu UHT", "Minuman", 20000, 35),
    new Produk("Keripik Singkong", "Makanan", 10000, 80)
};

List<Produk> stokAman = produk.Where(p => p.Stok > 30).ToList();
Produk[] arrayProduk = stokAman.ToArray();
Dictionary<string, int> harga = produk.ToDictionary(p => p.Nama, p => p.Harga);
object[] campuran = { 1, "dua", 3, "empat" };

Console.WriteLine($"List: {stokAman.Count} produk");
Console.WriteLine($"Array: {arrayProduk.Length} produk");
Console.WriteLine($"Harga Kopi Gayo: {harga["Kopi Gayo"]}");
Console.WriteLine($"OfType: {string.Join(" ", campuran.OfType<int>())}");

Output yang Dihasilkan:

text
List: 4 produk
Array: 4 produk
Harga Kopi Gayo: 25000
OfType: 1 3

Mari kita bedah baris demi baris:

  1. .Where(p => p.Stok > 30).ToList(): kueri dieksekusi seketika dan hasilnya disalin menjadi List<Produk> baru.
  2. stokAman.ToArray(): salinan kedua dibuat dari list; kedua wadah berdiri sendiri terhadap perubahan sumber.
  3. ToDictionary(p => p.Nama, p => p.Harga): kunci berupa nama produk dan nilai berupa harga, sehingga pencarian harga["Kopi Gayo"] berlangsung langsung.
  4. campuran.OfType<int>(): hanya elemen bertipe int yang dipertahankan dari array campuran; string dilewati tanpa exception.

Ikhtisar Operator Konversi #

OperatorHasilCatatan
ToListList<T>eksekusi segera
ToArrayT[]eksekusi segera
ToDictionaryDictionary<TKey,TValue>kunci wajib unik
OfType<T>elemen bertipe cocokmenyaring tanpa exception
Cast<T>semua elemen di-castmelempar exception bila tipe tak cocok

Dua operator lain melengkapi kelompok ini. ToLookup(p => p.Kategori) menghasilkan ILookup<TKey, TElement>, struktur mirip dictionary yang mengizinkan banyak nilai per kunci dan mengembalikan urutan kosong alih-alih exception bila kunci tidak ditemukan. AsEnumerable() tidak menyalin apa pun; method ini hanya mengubah tipe statis kueri menjadi IEnumerable<T> agar bagian lanjutan kueri dievaluasi di memori alih-alih diteruskan ke provider jarak jauh.

Perilaku eksekusi segera pada operator konversi dibedah lebih lanjut pada bab Immediate Execution, termasuk perannya sebagai snapshot data.