Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pengembang menggunakan generik sepanjang waktu di .NET, baik secara implisit maupun eksplisit. Ketika Anda menggunakan LINQ di .NET, apakah Anda menyadari bahwa Anda bekerja dengan IEnumerable<T>? Atau jika Anda pernah melihat sampel online dari "repositori generik" untuk berinteraksi dengan database menggunakan Entity Framework, apakah Anda melihat bahwa sebagian besar metode mengembalikan IQueryable<T>? Anda mungkin bertanya-tanya apa T dalam contoh-contoh ini dan mengapa T ada di sana.
Pertama kali diperkenalkan dalam .NET Framework 2.0, generik pada dasarnya adalah "templat kode" yang memungkinkan pengembang untuk menentukan struktur data jenis aman tanpa berkomitmen pada jenis data aktual. Misalnya, List<T> adalah koleksi generik yang dapat dideklarasikan dan digunakan dengan jenis apa pun, seperti List<int>, , List<string>atau List<Person>.
Untuk memahami mengapa generik berguna, mari kita lihat kelas tertentu sebelum dan sesudah menambahkan generik: ArrayList. Dalam .NET Framework 1.0, ArrayList elemennya berjenis Object. Elemen apa pun yang ditambahkan ke koleksi dikonversi secara diam-diam menjadi Object. Hal yang sama akan terjadi saat membaca elemen dari daftar. Proses ini dikenal sebagai pengkotakan dan pembongkaran, dan berdampak pada kinerja. Namun, selain performa, tidak ada cara untuk menentukan jenis data dalam daftar pada waktu kompilasi, yang membuat beberapa kode rapuh. Generik menyelesaikan masalah ini dengan mendefinisikan jenis data yang akan dimuat setiap instans daftar. Misalnya, Anda hanya dapat menambahkan bilangan bulat ke List<int> dan hanya menambahkan Orang ke List<Person>.
Generik juga tersedia saat waktu proses. Runtime mengetahui jenis struktur data apa yang Anda gunakan dan dapat menyimpannya dalam memori secara lebih efisien.
Contoh berikut adalah program kecil yang menggambarkan efisiensi mengetahui jenis struktur data saat runtime:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace GenericsExample {
class Program {
static void Main(string[] args) {
//generic list
List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
//non-generic list
ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
// timer for generic list sort
Stopwatch s = Stopwatch.StartNew();
ListGeneric.Sort();
s.Stop();
Console.WriteLine($"Generic Sort: {ListGeneric} \n Time taken: {s.Elapsed.TotalMilliseconds}ms");
//timer for non-generic list sort
Stopwatch s2 = Stopwatch.StartNew();
ListNonGeneric.Sort();
s2.Stop();
Console.WriteLine($"Non-Generic Sort: {ListNonGeneric} \n Time taken: {s2.Elapsed.TotalMilliseconds}ms");
Console.ReadLine();
}
}
}
Program ini menghasilkan output yang mirip dengan berikut ini:
Generic Sort: System.Collections.Generic.List`1[System.Int32]
Time taken: 0.0034ms
Non-Generic Sort: System.Collections.ArrayList
Time taken: 0.2592ms
Hal pertama yang dapat Anda perhatikan di sini adalah bahwa mengurutkan daftar generik secara signifikan lebih cepat daripada mengurutkan daftar non-generik. Anda mungkin juga melihat bahwa jenis untuk daftar generik berbeda ([System.Int32]), sedangkan jenis untuk daftar non-generik digeneralisasi. Karena runtime mengetahui generik List<int> berjenis Int32, maka dapat menyimpan elemen daftar ke dalam array bilangan bulat bawaan dalam memori, sementara non-generik ArrayList harus mengonversi setiap elemen daftar ke objek. Seperti yang ditunjukkan contoh ini, pemeran tambahan membutuhkan waktu dan memperlambat pengurutan daftar.
Keuntungan tambahan dari runtime yang mengenali jenis generik yang Anda gunakan adalah pengalaman debugging yang lebih baik. Saat Anda men-debug generik di C#, Anda tahu jenis apa yang ada di setiap elemen dalam struktur data Anda. Tanpa generik, Anda tidak akan tahu apa jenis setiap elemen.