Jenis anonim
Jenis anonim menyediakan cara mudah untuk merangkum sekumpulan properti baca-saja ke dalam satu objek tanpa harus secara eksplisit menentukan jenis terlebih dahulu. Nama jenis dihasilkan oleh kompilator dan tidak tersedia di tingkat kode sumber. Jenis setiap properti disimpulkan oleh kompilator.
Anda membuat jenis anonim dengan menggunakan operator new
bersama dengan penginisialisasi objek. Untuk informasi selengkapnya tentang penginisialisasi objek, lihat Penginisialisasi Objek dan Kumpulan.
Contoh berikut menunjukkan jenis anonim yang diinisialisasi dengan dua properti bernama Amount
dan Message
.
var v = new { Amount = 108, Message = "Hello" };
// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);
Jenis anonim biasanya digunakan dalam select
klausa ekspresi kueri untuk mengembalikan subset properti dari setiap objek dalam urutan sumber. Untuk informasi selengkapnya tentang kueri, lihat LINQ di C#.
Jenis anonim berisi satu atau beberapa properti baca-saja publik. Tidak ada jenis anggota kelas lain, seperti metode atau peristiwa yang valid. Ekspresi yang digunakan untuk menginisialisasi properti tidak boleh null
, fungsi anonim, atau jenis penunjuk.
Skenario yang paling umum adalah menginisialisasi jenis anonim dengan properti dari jenis lain. Dalam contoh berikut, asumsikan bahwa ada kelas bernama Product
. Kelas Product
mencakup Color
properti dan Price
, bersama dengan properti lain yang tidak Anda minati:
class Product
{
public string? Color {get;set;}
public decimal Price {get;set;}
public string? Name {get;set;}
public string? Category {get;set;}
public string? Size {get;set;}
}
Deklarasi jenis anonim dimulai dengan kata kunci new
. Deklarasi menginisialisasi jenis baru yang hanya menggunakan dua properti dari Product
. Menggunakan jenis anonim menyebabkan jumlah data yang lebih kecil dikembalikan dalam kueri.
Jika Anda tidak menentukan nama anggota dalam jenis anonim, kompilator memberi anggota jenis anonim nama yang sama dengan properti yang digunakan untuk menginisialisasinya. Anda memberikan nama untuk properti yang sedang diinisialisasi dengan ekspresi, seperti yang diperlihatkan dalam contoh sebelumnya. Dalam contoh berikut, nama properti dari jenis anonimnya adalah Color
dan Price
. Instans adalah item dari products
kumpulan jenis Product
:
var productQuery =
from prod in products
select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{
Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Tip
Anda dapat menggunakan aturan gaya .NET IDE0037 untuk memberlakukan apakah nama anggota yang disimpulkan atau eksplisit lebih diutamakan.
Dimungkinkan juga untuk menentukan bidang berdasarkan objek dari jenis lain: kelas, struct atau bahkan jenis anonim lainnya. Ini dilakukan dengan menggunakan variabel yang memegang objek ini sama seperti dalam contoh berikut, di mana dua jenis anonim dibuat menggunakan jenis yang sudah ditentukan pengguna yang sudah dibuat. Dalam kedua kasus, bidang dalam jenis shipment
anonim dan shipmentWithBonus
akan berjenis product
Product
yang berisi nilai defaultnya dari setiap bidang. bonus
Dan bidang akan berjenis anonim yang dibuat oleh pengompilasi.
var product = new Product();
var bonus = new { note = "You won!" };
var shipment = new { address = "Nowhere St.", product };
var shipmentWithBonus = new { address = "Somewhere St.", product, bonus };
Biasanya, ketika Anda menggunakan jenis anonim untuk menginisialisasi variabel, Anda mendeklarasikan variabel sebagai variabel lokal yang diketik secara implisit dengan menggunakan var. Nama jenis tidak dapat ditentukan dalam deklarasi variabel karena hanya kompilasi yang memiliki akses ke nama yang mendasar dari jenis anonim. Untuk informasi selengkapnya tentang var
, lihat Variabel Lokal yang Dijeniskan secara Implisit.
Anda dapat membuat lapisan elemen yang dijeniskan secara anonim dengan menggabungkan variabel lokal yang dijeniskan secara implisit dan lapisan yang dijeniskan secara implisit, seperti yang ditunjukkan dalam contoh berikut.
var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};
Anonim berjenis class
yang berasal langsung dari object
, dan yang tidak dapat dikonvesikan ke jenis apa pun kecuali object
. Kompilator menyediakan nama untuk setiap jenis anonim, meskipun aplikasi Anda tidak dapat mengaksesnya. Dari perspektif runtime bahasa umum, jenis anonim tidak berbeda dari jenis referensi lainnya.
Jika dua atau lebih penginisialisasi objek anonim dalam perakitan menentukan urutan properti yang berada dalam urutan yang sama dan yang memiliki nama dan jenis yang sama, pengompilasi memperlakukan objek sebagai instans dengan jenis yang sama. Mereka berbagi informasi jenis yang dihasilkan kompilator yang sama.
Jenis anonim mendukung mutasi non-destruktif dalam bentuk dengan ekspresi. Dengan ini Anda dapat membuat instans baru dari jenis anonim di mana satu atau beberapa properti memiliki nilai baru:
var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
Console.WriteLine(apple);
Console.WriteLine(onSale);
Anda tidak dapat mendeklarasikan bidang, properti, peristiwa, atau jenis pengembalian metode sebagai memiliki jenis anonim. Demikian pula, Anda tidak dapat mendeklarasikan parameter formal metode, properti, konstruktor, atau pengindeks sebagai memiliki jenis anonim. Untuk meneruskan jenis anonim, atau koleksi yang berisi jenis anonim, sebagai argumen ke metode, Anda dapat mendeklarasikan parameter sebagai jenis object
. Tetapi, menggunakan object
untuk jenis anonim mengalahkan tujuan pengetikan yang kuat. Jika Anda harus menyimpan hasil kueri atau meneruskannya di luar batas metode, pertimbangkan untuk menggunakan struktur atau kelas bernama biasa alih-alih jenis anonim.
Karena metode Equals dan GetHashCode pada jenis anonim didefinisikan dalam hal metode Equals
dan GetHashCode
dari properti, dua instans dengan jenis anonim yang sama hanya jika semua propertinya sama.
Catatan
Tingkat aksesibilitas jenis anonim adalah internal
, oleh karena itu dua jenis anonim yang ditentukan dalam rakitan yang berbeda bukan dari jenis yang sama.
Oleh karena itu, instans jenis anonim tidak dapat sama satu sama lain ketika didefinisikan dalam rakitan yang berbeda, bahkan ketika memiliki semua propertinya sama.
Jenis anonim mengambil alih ToString metode , menggabungkan nama dan ToString
output setiap properti yang dikelilingi oleh kurung kurawal.
var v = new { Title = "Hello", Age = 24 };
Console.WriteLine(v.ToString()); // "{ Title = Hello, Age = 24 }"