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.
10.1 Umum
Konversi menyebabkan ekspresi dikonversi ke, atau diperlakukan sebagai, jenis tertentu; dalam kasus sebelumnya konversi dapat melibatkan perubahan representasi. Konversi dapat bersifat implisit atau eksplisit, dan ini menentukan apakah cast eksplisit diperlukan.
Contoh: Misalnya, konversi dari jenis
intke jenislongbersifat implisit, sehingga ekspresi jenisintdapat secara implisit diperlakukan sebagai jenislong. Konversi yang berlawanan, dari jenislongke jenisint, eksplisit dan sehingga diperlukan pemeran eksplisit.int a = 123; long b = a; // implicit conversion from int to long int c = (int) b; // explicit conversion from long to intcontoh akhir
Beberapa konversi didefinisikan oleh bahasa. Program juga dapat menentukan konversi mereka sendiri (§10,5).
Beberapa konversi dalam bahasa ditentukan dari ekspresi ke jenis, yang lain dari jenis ke jenis. Konversi dari jenis berlaku untuk semua ekspresi yang memiliki jenis tersebut.
Contoh:
enum Color { Red, Blue, Green } // The expression 0 converts implicitly to enum types Color c0 = 0; // Other int expressions need explicit conversion Color c1 = (Color)1; // Conversion from null expression (no type) to string string x = null; // Conversion from lambda expression to delegate type Func<int, int> square = x => x * x;contoh akhir
10.2 Konversi implisit
10.2.1 Umum
Konversi berikut diklasifikasikan sebagai konversi implisit:
- Konversi identitas (§10.2.2)
- Konversi numerik implisit (§10.2.3)
- Konversi enumerasi implisit (§10.2.4)
- Konversi string terinterpolasi implisit (§10.2.5)
- Konversi referensi implisit (§10.2.8)
- Konversi tinju (§10.2.9)
- Konversi dinamis implisit (§10.2.10)
- Konversi parameter jenis implisit (§10.2.12)
- Konversi ekspresi konstanta implisit (§10.2.11)
- Konversi implisit yang ditentukan pengguna (termasuk diangkat) (§10.2.14)
- Konversi fungsi anonim (§10.2.15)
- Konversi grup metode (§10.2.15)
- Konversi harfiah null (§10.2.7)
- Konversi implisit nullable (§10.2.6)
- Konversi tuple implisit (§10.2.13)
- Konversi literal default (§10.2.16)
- Konversi lemparan implisit (§10.2.17)
Konversi implisit dapat terjadi dalam berbagai situasi, termasuk pemanggilan anggota fungsi (§12.6.6), ekspresi cast (§12.9.8), dan penugasan (§12,23).
Konversi implisit yang telah ditentukan sebelumnya selalu berhasil dan tidak pernah menyebabkan pengecualian dilemparkan.
Catatan: Konversi implisit yang ditentukan pengguna yang dirancang dengan benar juga harus menunjukkan karakteristik ini. catatan akhir
Untuk tujuan konversi, jenis object dan dynamic dapat dikonversi identitas (§10.2.2).
Namun, konversi dinamis (§10.2.10) hanya berlaku untuk ekspresi jenis dynamic (§8.2.4).
10.2.2 Konversi identitas
Konversi identitas dikonversi dari jenis apa pun ke jenis yang sama atau jenis yang setara pada runtime. Salah satu alasan konversi ini ada sehingga jenis T atau ekspresi jenis T dapat dikatakan dapat dikonversi ke T dirinya sendiri. Konversi identitas berikut ada:
- Antara
TdanT, untuk semua jenisT. - Antara
TdanT?untuk jenisTreferensi apa pun . - Antara
objectdandynamic. - Antara semua jenis tuple dengan aritas yang sama, dan jenis konstruksi yang sesuai
ValueTuple<...>, ketika konversi identitas ada di antara setiap pasangan jenis elemen yang sesuai. - Antara jenis yang dibangun dari jenis generik yang sama di mana ada konversi identitas antara setiap argumen jenis yang sesuai.
Contoh: Berikut ini menggambarkan sifat rekursif dari aturan ketiga:
(int a , string b) t1 = (1, "two"); (int c, string d) t2 = (3, "four"); // Identity conversions exist between // the types of t1, t2, and t3. var t3 = (5, "six"); t3 = t2; t2 = t1; var t4 = (t1, 7); var t5 = (t2, 8); // Identity conversions exist between // the types of t4, t5, and t6. var t6 =((8, "eight"), 9); t6 = t5; t5 = t4;Jenis tuple
t1,t2dant3semuanya memiliki dua elemen: diikutiintolehstring. Jenis elemen tuple dapat sendiri dengan tuple, seperti dalamt4,t5, dant6. Konversi identitas ada di antara setiap pasangan jenis elemen yang sesuai, termasuk tuple berlapis, oleh karena itu konversi identitas ada di antara jenis tuplet4, ,t5dant6.contoh akhir
Semua konversi identitas bersifat simetris. Jika konversi identitas ada dari T₁ ke T₂, maka konversi identitas ada dari T₂ ke T₁. Dua jenis dapat dikonversi identitas ketika konversi identitas ada di antara dua jenis.
Dalam kebanyakan kasus, konversi identitas tidak berpengaruh pada runtime. Namun, karena operasi floating point dapat dilakukan pada presisi yang lebih tinggi daripada yang ditentukan oleh jenisnya (§8.3.7), penugasan hasilnya dapat mengakibatkan hilangnya presisi, dan cast eksplisit dijamin untuk mengurangi presisi terhadap apa yang ditentukan oleh jenis (§12.9.8).
10.2.3 Konversi numerik implisit
Konversi numerik implisit adalah:
- Dari
sbytekeshort,int,long,float,double, ataudecimal. - Dari
bytekeshort,ushort,int,uint,long,ulong,float,double, ataudecimal. - Dari
shortkeint,long,float,double, ataudecimal. - Dari
ushortkeint,uint,long,ulong,float,double, ataudecimal. - Dari
intkelong,float,double, ataudecimal. - Dari
uintkelong,ulong,float,double, ataudecimal. - Dari
longkefloat,double, ataudecimal. - Dari
ulongkefloat,double, ataudecimal. - Dari
charkeushort,int,uint,long,ulong,float,double, ataudecimal. - Dari
floatsampaidouble.
Konversi dari int, , uintlong atau ulong ke float dan dari long atau ulong ke double dapat menyebabkan hilangnya presisi, tetapi tidak akan pernah menyebabkan hilangnya besaran. Konversi numerik implisit lainnya belum pernah kehilangan informasi apa pun.
Tidak ada konversi implisit yang telah ditentukan sebelumnya ke char jenis , sehingga nilai jenis integral lainnya tidak secara otomatis dikonversi ke jenis .char
10.2.4 Konversi enumerasi implisit
Konversi enumerasi implisit memungkinkan constant_expression (§12,25) dengan jenis bilangan bulat apa pun dan nilai nol untuk dikonversi ke enum_type apa pun dan ke nullable_value_type yang jenis yang mendasarnya adalah enum_type. Dalam kasus terakhir, konversi dievaluasi dengan mengonversi ke enum_type yang mendasar dan membungkus hasilnya (§8.3.12).
10.2.5 Konversi string terinterpolasi implisit
Konversi string terinterpolasi implisit mengizinkan interpolated_string_expression (§12.8.3) untuk dikonversi ke System.IFormattable atau System.FormattableString (yang mengimplementasikan System.IFormattable).
Ketika konversi ini diterapkan, nilai string tidak terdiri dari string terinterpolasi. Sebagai gantinya, instans System.FormattableString dibuat, seperti yang dijelaskan lebih lanjut dalam §12.8.3.
10.2.6 Konversi implisit nullable
Konversi implisit nullable adalah konversi nullable (§10.6.1) yang berasal dari konversi implisit yang telah ditentukan sebelumnya.
10.2.7 Konversi harfiah null
Konversi implisit ada dari null literal ke jenis referensi apa pun atau jenis nilai nullable. Konversi ini menghasilkan referensi null jika jenis target adalah jenis referensi, atau nilai null (§8.3.12) dari jenis nilai nullable yang diberikan.
10.2.8 Konversi referensi implisit
Konversi referensi implisit adalah:
- Dari reference_type ke
objectdandynamic. - Dari class_type
Shingga class_type, yang disediakanTberasal dariS. - Dari class_typehingga interface_type
S, yang disediakan mengimplementasikanT. - Dari interface_type
Shingga interface_type, yang disediakanTberasal dariS. -
dengan jenis
Selemen keSᵢdengan jenisTelemen , asalkan semua hal berikut ini benar:-
SdanThanya berbeda dalam jenis elemen. Dengan kata lain,SdanTmemiliki jumlah dimensi yang sama. - Konversi referensi implisit ada dari
SᵢkeTᵢ.
-
- Dari jenis
S[]array dimensi tunggal keSystem.Collections.Generic.IList<T>,System.Collections.Generic.IReadOnlyList<T>, dan antarmuka dasarnya, asalkan ada konversi identitas atau referensi implisit dariSkeT. - Dari array_type apa pun hingga
System.Arraydan antarmuka yang diimplementasikannya. - Dari delegate_type apa pun hingga
System.Delegatedan antarmuka yang diimplementasikannya. - Dari literal null (§6.4.5.7) hingga jenis referensi apa pun.
- Dari reference_type apa pun
- Dari reference_type apa pun ke antarmuka atau jenis
Tdelegasi jika memiliki identitas implisit atau konversi referensi ke antarmuka atau jenisT₀delegasi danT₀dapat dikonversi varians (§19.2.3.3) keT. - Konversi implisit yang melibatkan parameter jenis yang dikenal sebagai jenis referensi. Lihat §10.2.12 untuk detail selengkapnya tentang konversi implisit yang melibatkan parameter jenis.
Konversi referensi implisit adalah konversi antara reference_typeyang dapat terbukti selalu berhasil, dan karenanya tidak memerlukan pemeriksaan pada run-time.
Konversi referensi, implisit atau eksplisit, tidak pernah mengubah identitas referensial objek yang dikonversi.
Catatan: Dengan kata lain, sementara konversi referensi dapat mengubah jenis referensi, itu tidak pernah mengubah jenis atau nilai objek yang dirujuk. catatan akhir
10.2.9 Konversi Tinju
Konversi tinju memungkinkan value_type dikonversi secara implisit ke reference_type. Konversi tinju berikut ada:
- Dari value_type apa pun
- Dari value_type apa pun
- Dari enum_type apa pun
- Dari non_nullable_value_type apa pun hingga interface_type apa pun yang diterapkan oleh non_nullable_value_type.
- Dari non_nullable_value_type apa pun
- Dari non_nullable_value_type apa pun ke interface_type
Iapa pun sehingga ada konversi tinju dari non_nullable_value_type ke interface_typeI₀lain, danI₀dapat dikonversi varians (§19.2.3.3) keI. - Dari nullable_value_type apa pun ke reference_type mana pun di mana ada konversi tinju dari jenis nullable_value_type yang mendasar ke reference_type.
- Dari parameter jenis yang tidak diketahui sebagai jenis referensi ke jenis apa pun sehingga konversi diizinkan oleh §10.2.12.
Tinju nilai jenis nilai yang tidak dapat diubah ke null terdiri dari mengalokasikan instans objek dan menyalin nilai ke dalam instans tersebut.
Tinju nilai nullable_value_type menghasilkan referensi null jika itu adalah nilai null (HasValue salah), atau hasil pembongkaran dan tinju nilai yang mendasar sebaliknya.
Catatan: Proses tinju dapat dibayangkan dalam hal keberadaan kelas tinju untuk setiap jenis nilai. Misalnya, pertimbangkan
struct Suntuk menerapkan antarmukaI, dengan kelas tinju yang disebutS_Boxing.interface I { void M(); } struct S : I { public void M() { ... } } sealed class S_Boxing : I { S value; public S_Boxing(S value) { this.value = value; } public void M() { value.M(); } }Tinju nilai
vjenisSsekarang terdiri dari menjalankan ekspresinew S_Boxing(v)dan mengembalikan instans yang dihasilkan sebagai nilai dari jenis target konversi. Dengan demikian, pernyataanS s = new S(); object box = s;dapat dianggap mirip dengan:
S s = new S(); object box = new S_Boxing(s);Jenis tinju yang dibayangkan yang dijelaskan di atas sebenarnya tidak ada. Sebagai gantinya, nilai berkotak jenis
Smemiliki jenisSruntime , dan pemeriksaan jenis runtime menggunakanisoperator dengan jenis nilai sebagai uji operand kanan apakah operand kiri adalah versi kotak dari operand kanan. Contohnya,int i = 123; object box = i; if (box is int) { Console.Write("Box contains an int"); }akan menghasilkan yang berikut:
Box contains an intKonversi tinju menyiratkan pembuatan salinan nilai yang dikotak. Ini berbeda dari konversi reference_type ke jenis
object, di mana nilai terus mereferensikan instans yang sama dan hanya dianggap sebagai jenisobjectyang kurang diturunkan . Misalnya, berikut inistruct Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } class A { void M() { Point p = new Point(10, 10); object box = p; p.x = 20; Console.Write(((Point)box).x); } }akan menghasilkan nilai 10 pada konsol karena operasi tinju implisit yang terjadi dalam penugasan
pmenyebabkanboxnilaipdisalin. TelahPointdinyatakan sebagaiclassgantinya, nilai 20 akan menjadi output karenapdanboxakan mereferensikan instans yang sama.Analogi kelas tinju tidak boleh digunakan sebagai lebih dari alat bermanfaat untuk menggambarkan cara kerja tinju secara konseptual. Ada banyak perbedaan halus antara perilaku yang dijelaskan oleh spesifikasi ini dan perilaku yang akan mengakibatkan tinju diimplementasikan dengan tepat dengan cara ini.
catatan akhir
10.2.10 Konversi dinamis implisit
Konversi dinamis implisit ada dari ekspresi jenis dinamis ke jenis Tapa pun . Konversi terikat secara dinamis §12.3.3, yang berarti bahwa konversi implisit akan dicari pada run-time dari jenis run-time ekspresi ke T. Jika tidak ada konversi yang ditemukan, pengecualian run-time akan dilemparkan.
Konversi implisit ini tampaknya melanggar saran di awal §10.2 bahwa konversi implisit tidak boleh menyebabkan pengecualian. Namun, itu bukan konversi itu sendiri, tetapi temuan konversi yang menyebabkan pengecualian. Risiko pengecualian run-time melekat dalam penggunaan pengikatan dinamis. Jika pengikatan dinamis konversi tidak diinginkan, ekspresi dapat terlebih dahulu dikonversi ke object, lalu ke jenis yang diinginkan.
Contoh: Berikut ini menggambarkan konversi dinamis implisit:
object o = "object"; dynamic d = "dynamic"; string s1 = o; // Fails at compile-time – no conversion exists string s2 = d; // Compiles and succeeds at run-time int i = d; // Compiles but fails at run-time – no conversion existsPenugasan ke
s2danikeduanya menggunakan konversi dinamis implisit, di mana pengikatan operasi ditangguhkan hingga run-time. Pada run-time, konversi implisit dicari dari jenisdrun-time (string) ke jenis target. Konversi ditemukan tetapistringtidak keint.contoh akhir
10.2.11 Konversi ekspresi konstanta implisit
Konversi ekspresi konstanta implisit mengizinkan konversi berikut:
- Jenis constant_expression (
int) dapat dikonversi ke jenissbyte, ,byte,shortushort,uint, atauulong, asalkan nilai constant_expression berada dalam rentang jenis tujuan. - Constant_expression jenis
longdapat dikonversi ke jenisulong, asalkan nilai constant_expression tidak negatif.
10.2.12 Konversi implisit yang melibatkan parameter jenis
yang dikenal sebagai jenis referensi (T), konversi referensi implisit berikut (§10.2.8) ada:
- Dari ke kelas
Tdasar yang efektif , dariCke kelas dasar apa pun ,Tdan dariCke antarmuka apa pun yang diimplementasikan olehT.C - Dari
Tke interface_typeIdalamTset antarmuka efektif dan dariTke antarmuka dasar apa pun dariI. - Dari
Tke parameterUjenis yang disediakan yangTbergantung padaU(§15.2.5).Catatan: Karena
Tdikenal sebagai jenis referensi, dalam lingkupT, jenisUrun-time akan selalu menjadi jenis referensi, bahkan jikaUtidak diketahui sebagai jenis referensi pada waktu kompilasi. catatan akhir - Dari harfiah null (§6.4.5.7) hingga T.
yang T diketahui sebagai jenis referensi §15.2.5, konversi berikut yang melibatkan dianggap sebagai konversi tinju (T) pada waktu kompilasi. Pada run-time, jika T adalah jenis nilai, konversi dijalankan sebagai konversi tinju. Pada run-time, jika T merupakan jenis referensi, konversi dijalankan sebagai konversi referensi implisit atau konversi identitas.
- Dari ke kelas
Tdasar yang efektif , dariCke kelas dasar apa pun ,Tdan dariCke antarmuka apa pun yang diimplementasikan olehT.CCatatan:
Cakan menjadi salah satu jenisSystem.Object, ,System.ValueTypeatauSystem.Enum(jika tidakT, akan diketahui sebagai jenis referensi). catatan akhir - Dari
Tke interface_typeIdalamTset antarmuka efektif dan dariTke antarmuka dasar apa pun dariI.
yang T diketahui sebagai jenis referensi, ada konversi implisit dari ke parameter T jenis yang disediakan U tergantung pada T. Pada run-time, jika T adalah jenis nilai dan U merupakan jenis referensi, konversi dijalankan sebagai konversi tinju. Pada run-time, jika dan TU merupakan jenis nilai, maka T dan U harus jenis yang sama dan tidak ada konversi yang dilakukan. Pada run-time, jika T adalah jenis referensi, maka U tentu juga merupakan jenis referensi dan konversi dijalankan sebagai konversi referensi implisit atau konversi identitas (§15.2.5).
Konversi implisit lebih lanjut berikut ada untuk parameter Tjenis tertentu :
- Dari
Tke jenisSreferensi jika memiliki konversi implisit ke jenisS₀referensi danS₀memiliki konversi identitas keS. Pada run-time, konversi dijalankan dengan cara yang sama seperti konversi keS₀. - Dari
Tke jenisIantarmuka jika memiliki konversi implisit ke jenisI₀antarmuka , danI₀dapat dikonversi varians keI(§19.2.3.3). Pada run-time, jikaTadalah jenis nilai, konversi dijalankan sebagai konversi tinju. Jika tidak, konversi dijalankan sebagai konversi referensi implisit atau konversi identitas.
Dalam semua kasus, aturan memastikan bahwa konversi dijalankan sebagai konversi tinju jika dan hanya jika pada run-time konversi berasal dari jenis nilai ke jenis referensi.
10.2.13 Konversi tuple implisit
Konversi implisit ada dari ekspresi E tuple ke jenis T tuple jika E memiliki aritas yang sama dengan T dan konversi implisit ada dari setiap elemen ke E jenis elemen yang sesuai di T. Konversi dilakukan dengan membuat instans jenis Tyang System.ValueTuple<...> sesuai, dan menginisialisasi setiap bidangnya secara berurutan dari kiri ke kanan dengan mengevaluasi ekspresi Eelemen tuple yang sesuai , mengonversinya ke jenis elemen yang sesuai menggunakan T konversi implisit yang ditemukan, dan menginisialisasi bidang dengan hasilnya.
Jika nama elemen dalam ekspresi tuple tidak cocok dengan nama elemen yang sesuai dalam jenis tuple, peringatan akan dikeluarkan.
Contoh:
(int, string) t1 = (1, "One"); (byte, string) t2 = (2, null); (int, string) t3 = (null, null); // Error: No conversion (int i, string s) t4 = (i: 4, "Four"); (int i, string) t5 = (x: 5, s: "Five"); // Warning: Names are ignoredDeklarasi
t1,t2,t4dant5semuanya valid, karena konversi implisit ada dari ekspresi elemen ke jenis elemen yang sesuai. Deklarasit3tidak valid, karena tidak ada konversi darinullkeint. Deklarasit5menyebabkan peringatan karena nama elemen dalam ekspresi tuple berbeda dari yang ada di jenis tuple.contoh akhir
10.2.14 Konversi implisit yang ditentukan pengguna
Konversi implisit yang ditentukan pengguna terdiri dari konversi implisit standar opsional, diikuti dengan eksekusi operator konversi implisit yang ditentukan pengguna, diikuti oleh konversi implisit standar opsional lainnya. Aturan yang tepat untuk mengevaluasi konversi implisit yang ditentukan pengguna dijelaskan dalam §10.5.4.
10.2.15 Konversi fungsi anonim dan konversi grup metode
Fungsi anonim dan grup metode tidak memiliki jenis dalam dan dari diri mereka sendiri, tetapi mungkin secara implisit dikonversi untuk mendelegasikan jenis. Selain itu, beberapa ekspresi lambda dapat dikonversi secara implisit ke jenis pohon ekspresi. Konversi fungsi anonim dijelaskan secara lebih rinci dalam §10,7 dan konversi grup metode dalam §10,8.
10.2.16 Konversi literal default
Konversi implisit ada dari default_literal (§12.8.21) ke jenis apa pun. Konversi ini menghasilkan nilai default (§9,3) dari jenis yang disimpulkan.
10.2.17 Konversi lemparan implisit
Meskipun ekspresi lemparan tidak memiliki jenis, ekspresi mungkin dikonversi secara implisit ke jenis apa pun.
10.2.18 Beralih konversi ekspresi
Ada konversi implisit dari switch_expression (§12.11) ke setiap jenis T yang ada konversi implisit dari setiap switch_expression_arm_expression switch_expression_arm menjadi .T
10.3 Konversi eksplisit
10.3.1 Umum
Konversi berikut diklasifikasikan sebagai konversi eksplisit:
- Semua konversi implisit (§10.2)
- Konversi numerik eksplisit (§10.3.2)
- Konversi enumerasi eksplisit (§10.3.3)
- Konversi nullable eksplisit (§10.3.4)
- Konversi tuple eksplisit (§10.3.6)
- Konversi referensi eksplisit (§10.3.5)
- Konversi antarmuka eksplisit
- Membatalkan konversi kotak (§10.3.7)
- Konversi parameter jenis eksplisit (§10.3.8)
- Konversi eksplisit yang ditentukan pengguna (§10.3.9)
Konversi eksplisit dapat terjadi dalam ekspresi pemeran (§12.9.8).
Kumpulan konversi eksplisit mencakup semua konversi implisit.
Catatan: Ini, misalnya, memungkinkan cast eksplisit digunakan ketika konversi identitas implisit ada, untuk memaksa pemilihan metode tertentu kelebihan beban. catatan akhir
Konversi eksplisit yang bukan konversi implisit adalah konversi yang tidak dapat dibuktikan selalu berhasil, konversi yang diketahui mungkin kehilangan informasi, dan konversi di seluruh domain jenis yang cukup berbeda untuk merit notasi eksplisit.
10.3.2 Konversi numerik eksplisit
Konversi numerik eksplisit adalah konversi dari numeric_type ke numeric_type lain yang konversi numerik implisitnya (§10.2.3) belum ada:
- Dari
sbytekebyte,ushort,uint,ulong, atauchar. - Dari
bytekesbyteatauchar. - Dari
shortkesbyte,byte,ushort,uint,ulong, atauchar. - Dari
ushortkesbyte,byte,short, atauchar. - Dari
intkesbyte,byte,short,ushort,uint,ulong, atauchar. - Dari
uintkesbyte,byte,short,ushort,int, atauchar. - Dari
longkesbyte,byte,short,ushort,int,uint,ulong, atauchar. - Dari
ulongkesbyte,byte,short,ushort,int,uint,long, atauchar. - Dari
charkesbyte,byte, ataushort. - Dari
floatkesbyte,byte,short,ushort,int,uint,long,ulong, ,char, ataudecimal. - Dari
doublekesbyte,byte,short,ushort,int,uint,long,ulong,char, ,float, ataudecimal. - Dari
decimalkesbyte,byte,short,ushort,int,uint,long,ulong,char, ,float, ataudouble.
Karena konversi eksplisit mencakup semua konversi numerik implisit dan eksplisit, selalu dimungkinkan untuk mengonversi dari numeric_type apa pun ke numeric_type lain menggunakan ekspresi pemeran (§12.9.8).
Konversi numerik eksplisit mungkin kehilangan informasi atau mungkin menyebabkan pengecualian dilemparkan. Konversi numerik eksplisit diproses sebagai berikut:
- Untuk konversi dari jenis integral ke jenis integral lain, pemrosesan tergantung pada konteks pemeriksaan luapan (§12.8.20) di mana konversi terjadi:
-
checkedDalam konteks, konversi berhasil jika nilai operand sumber berada dalam rentang jenis tujuan, tetapi melemparkanSystem.OverflowExceptionjika nilai operand sumber berada di luar rentang jenis tujuan. - Dalam konteks
unchecked, konversi selalu berhasil, dan berlanjut sebagai berikut.- Jika jenis sumber lebih besar dari jenis tujuan, maka nilai sumber dipotong dengan membuang bit "ekstra" yang paling signifikan. Hasilnya kemudian diperlakukan sebagai nilai dari jenis tujuannya.
- Jika jenis sumber berukuran sama dengan jenis tujuan, maka nilai sumber diperlakukan sebagai nilai dari jenis tujuan
-
- Untuk konversi dari
decimalke jenis integral, nilai sumber dibulatkan ke nol ke nilai integral terdekat, dan nilai integral ini menjadi hasil konversi. Jika nilai integral yang dihasilkan berada di luar rentang jenis tujuan, akanSystem.OverflowExceptiondilemparkan. - Untuk konversi dari
floatataudoubleke jenis integral, pemrosesan tergantung pada konteks pemeriksaan luapan (§12.8.20) tempat konversi berlangsung:- Dalam konteks yang dicentang, konversi berlanjut sebagai berikut:
- Jika nilai operand adalah NaN atau tak terbatas, akan
System.OverflowExceptiondilemparkan. - Jika tidak, operand sumber dibulatkan menuju nol ke nilai integral terdekat. Jika nilai integral ini berada dalam rentang jenis tujuan, maka nilai ini adalah hasil konversi.
- Jika tidak, dilemparkan
System.OverflowException.
- Jika nilai operand adalah NaN atau tak terbatas, akan
- Dalam konteks yang tidak dicentang, konversi selalu berhasil, dan berlanjut sebagai berikut.
- Jika nilai operand adalah NaN atau tak terbatas, hasil konversi adalah nilai yang tidak ditentukan dari jenis tujuan.
- Jika tidak, operand sumber dibulatkan menuju nol ke nilai integral terdekat. Jika nilai integral ini berada dalam rentang jenis tujuan, maka nilai ini adalah hasil konversi.
- Jika tidak, hasil konversi adalah nilai yang tidak ditentukan dari jenis tujuan.
- Dalam konteks yang dicentang, konversi berlanjut sebagai berikut:
- Untuk konversi dari
doublekefloat, nilai dibulatkandoubleke nilai terdekatfloat.doubleJika nilai terlalu kecil untuk diwakili sebagaifloat, hasilnya menjadi nol dengan tanda yang sama dengan nilai . Jika besarnyadoublenilai terlalu besar untuk diwakili sebagaifloat, hasilnya menjadi tak terbatas dengan tanda yang sama dengan nilai . Jika nilainyadoubleadalah NaN, hasilnya juga NaN. - Untuk konversi dari atau ke , nilai sumber dikonversi ke
floatrepresentasi dan dibulatkan ke angka terdekat jika diperlukan (double).decimaldecimal- Jika nilai sumber terlalu kecil untuk direpresentasikan sebagai
decimal, hasilnya menjadi nol, mempertahankan tanda nilai asli jikadecimalmendukung nilai nol yang ditandatangani. - Jika besarnya nilai sumber terlalu besar untuk direpresentasikan sebagai
decimal, atau nilai tersebut tidak terbatas, hasilnya adalah infinity mempertahankan tanda nilai asli, jika representasi desimal mendukung tak terbatas; jika tidak, System.OverflowException akan dilemparkan. - Jika nilai sumber adalah NaN, hasilnya adalah NaN jika representasi desimal mendukung NaN; jika tidak, System.OverflowException dilemparkan.
- Jika nilai sumber terlalu kecil untuk direpresentasikan sebagai
- Untuk konversi dari
decimalkefloatataudouble, nilai dibulatkandecimalke nilai terdekatdoubleataufloat. Jika besarnya nilai sumber terlalu besar untuk diwakili dalam jenis target, atau nilai tersebut tidak terbatas, hasilnya adalah infinity mempertahankan tanda nilai asli. Jika nilai sumber adalah NaN, hasilnya adalah NaN. Meskipun konversi ini mungkin kehilangan presisi, itu tidak pernah menyebabkan pengecualian dilemparkan.
Catatan:
decimalJenis ini tidak diperlukan untuk mendukung nilai infinities atau NaN tetapi dapat melakukannya; rentangnya mungkin lebih kecil dari rentangfloatdandouble, tetapi tidak dijamin. Untukdecimalrepresentasi tanpa nilai infinities atau NaN, dan dengan rentang yang lebih kecil darifloat, hasil konversi daridecimalke ataufloatdoubletidak akan pernah tak terbatas atau NaN. catatan akhir
10.3.3 Konversi enumerasi eksplisit
Konversi enumerasi eksplisit adalah:
- Dari
sbyte, ,byteshort,ushort,intuint, ,long,ulong,char,float,double, , ataudecimalke enum_type apa pun. - Dari enum_type apa pun
- Dari enum_type ke enum_type lainnya.
Konversi enumerasi eksplisit antara dua jenis diproses dengan memperlakukan enum_type yang berpartisipasi sebagai jenis yang mendasar dari enum_type tersebut, lalu melakukan konversi numerik implisit atau eksplisit antara jenis yang dihasilkan.
Contoh: Mengingat enum_type
Edengan jenisintyang mendasar , konversi dariEkebytediproses sebagai konversi numerik eksplisit (§10,3,2) dariintkebyte, dan konversi daribytekeEdiproses sebagai konversi numerik implisit (§10,2,3) daribytekeint. contoh akhir
10.3.4 Konversi nullable eksplisit
Konversi nullable eksplisit adalah konversi nullable (§10.6.1) yang berasal dari konversi eksplisit dan implisit yang telah ditentukan sebelumnya.
10.3.5 Konversi referensi eksplisit
Konversi referensi eksplisit adalah:
- Dari objek ke reference_type lainnya.
- Dari class_typehingga class_type
S, yang disediakan adalah kelas dasar .T - Dari class_type apa pun
S - Dari interface_type apa pun
S - Dari interface_type
Shingga interface_type, yang disediakanTtidak berasal dariS. -
dengan jenis
Selemen keSᵢdengan jenisTelemen , asalkan semua hal berikut ini benar:-
SdanThanya berbeda dalam jenis elemen. Dengan kata lain,SdanTmemiliki jumlah dimensi yang sama. - Konversi referensi eksplisit ada dari
SᵢkeTᵢ.
-
- Dari
System.Arraydan antarmuka yang diimplementasikannya, ke array_type apa pun. - Dari array_type
S[]ada konversi identitas atau konversi referensi eksplisit dariSystem.Collections.Generic.IList<T>keSystem.Collections.Generic.IReadOnlyList<T>. - Dari
System.Collections.Generic.IList<S>,System.Collections.Generic.IReadOnlyList<S>, dan antarmuka dasarnya ke jenisT[]array dimensi tunggal , asalkan ada konversi identitas atau konversi referensi eksplisit dariSke T. - Dari
System.Delegatedan antarmuka yang diimplementasikannya ke delegate_type apa pun. - Dari jenis
Sreferensi ke jenisTreferensi jika memiliki konversi referensi eksplisit dariSke jenisT₀referensi danT₀dan ada konversi identitas dariT₀keT. - Dari jenis
Sreferensi ke antarmuka atau jenisTdelegasi jika ada konversi referensi eksplisit dariSke antarmuka atau jenisT₀delegasi dan dapatT₀dikonversi varians keTatauTdapat dikonversiT₀ke §19.2.3.3. - Dari
D<S₁...Sᵥ>keD<T₁...Tᵥ>tempatD<X₁...Xᵥ>adalah jenis delegasi generik,D<S₁...Sᵥ>tidak kompatibel dengan atau identikD<T₁...Tᵥ>dengan , dan untuk setiap parameterXᵢjenis penangguhanDberikut:- Jika
Xᵢinvarian, makaSᵢidentik denganTᵢ. - Jika
Xᵢkovarian, maka ada konversi identitas, konversi referensi implisit, atau konversi referensi eksplisit dariSᵢkeTᵢ. - Jika
Xᵢkontravarian, makaSᵢdanTᵢmerupakan jenis referensi yang identik atau keduanya.
- Jika
- Konversi eksplisit yang melibatkan parameter jenis yang diketahui sebagai jenis referensi. Untuk detail selengkapnya tentang konversi eksplisit yang melibatkan parameter jenis, lihat §10.3.8.
Konversi referensi eksplisit adalah konversi antara reference_typeyang memerlukan pemeriksaan run-time untuk memastikan konversi tersebut benar.
Agar konversi referensi eksplisit berhasil pada run-time, nilai operand sumber harus , atau jenis objek yang direferensikan nulloleh operand sumber adalah jenis yang dapat dikonversi ke jenis tujuan dengan konversi referensi implisit (§10.2.8). Jika konversi referensi eksplisit gagal, akan System.InvalidCastException dilemparkan.
Catatan: Konversi referensi, implisit atau eksplisit, tidak pernah mengubah nilai referensi itu sendiri (§8.2.1), hanya jenisnya; tidak mengubah jenis atau nilai objek yang dirujuk. catatan akhir
10.3.6 Konversi tuple eksplisit
Konversi eksplisit ada dari ekspresi E tuple ke jenis T tuple jika E memiliki aritas yang sama dengan T dan konversi implisit atau eksplisit ada dari setiap elemen ke E jenis elemen yang sesuai di T. Konversi dilakukan dengan membuat instans jenis Tyang System.ValueTuple<...> sesuai, dan menginisialisasi setiap bidangnya secara berurutan dari kiri ke kanan dengan mengevaluasi ekspresi elemen tuple yang sesuai dari E, mengonversinya ke jenis elemen yang sesuai menggunakan T konversi eksplisit yang ditemukan, dan menginisialisasi bidang dengan hasilnya.
10.3.7 Konversi unboxing
Konversi pembatalan kotak memungkinkan reference_type dikonversi secara eksplisit ke value_type. Konversi pembukaan kotak berikut ada:
- Dari jenis
objectke value_type apa pun. - Dari jenis
System.ValueTypeke value_type apa pun. - Dari jenis
System.Enumke enum_type apa pun. - Dari interface_type apa pun hingga non_nullable_value_type apa pun yang mengimplementasikan interface_type.
- Dari interface_type apa pun
Ike non_nullable_value_type di mana ada konversi pembukaan kotak dari interface_typeI₀ke jenis non_nullable_value dan konversi identitas dariIkeI₀. - Dari interface_type
Iapa pun ke non_nullable_value_type di mana ada konversi pembatalan kotak dari interface_typeI₀ke non_nullable_value_type dan variance_convertibleI₀keIatauIdapat dikonversi varians keI₀(§19.2.3.3). - Dari reference_type apa pun ke nullable_value_type mana pun di mana ada konversi pembukaan kotak dari reference_type ke non_nullable_value_type yang mendasar dari nullable_value_type.
- Dari parameter jenis yang tidak diketahui sebagai jenis nilai ke jenis apa pun sehingga konversi diizinkan oleh §10.3.8.
Operasi pembukaan kotak ke non_nullable_value_type terdiri dari pemeriksaan pertama bahwa instans objek adalah nilai kotak dari non_nullable_value_type yang diberikan, lalu menyalin nilai dari instans.
Membuka kotak ke nullable_value_type menghasilkan nilai null nullable_value_type jika operand sumber adalah null, atau hasil yang dibungkus dari membuka kotak instans objek ke jenis nullable_value_type yang mendasar jika tidak.
Catatan: Mengacu pada kelas tinju imajiner yang dijelaskan dalam §10.2.9, konversi pembatalan kotak objek ke value_type
Sterdiri dari menjalankan ekspresi((S_Boxing)box).value. Dengan demikian, pernyataanobject box = new S(); S s = (S)box;secara konseptual sesuai dengan
object box = new S_Boxing(new S()); S s = ((S_Boxing)box).value;catatan akhir
Agar konversi pembukaan kotak ke non_nullable_value_type tertentu berhasil pada run-time, nilai operand sumber harus menjadi referensi ke nilai kotak dari non_nullable_value_type tersebut. Jika operand sumber adalah null dilemparkan System.NullReferenceException . Jika operand sumber adalah referensi ke objek yang tidak kompatibel, akan System.InvalidCastException dilemparkan.
Agar konversi pembukaan kotak ke nullable_value_type tertentu berhasil pada run-time, nilai operand sumber harus null atau referensi ke nilai kotak dari non_nullable_value_type yang mendasari nullable_value_type. Jika operand sumber adalah referensi ke objek yang tidak kompatibel, akan System.InvalidCastException dilemparkan.
10.3.8 Konversi eksplisit yang melibatkan parameter jenis
yang dikenal sebagai jenis referensi (T), konversi referensi eksplisit berikut (§10.3.5) ada:
- Dari kelas
Cdasar yang efektif dariTkeTdan dari kelas dasar apa pun hinggaCT. - Dari interface_type apa pun hingga
T. - Dari
Tke interface_typeyang disediakan belum ada konversi referensi implisit dariIkeT. -
Dari type_parameter
UyangTdisediakan tergantungTpadaU(§15.2.5).Catatan: Karena
Tdikenal sebagai jenis referensi, dalam cakupanT, jenis run-time Anda akan selalu menjadi jenis referensi, bahkan jikaUtidak diketahui sebagai jenis referensi pada waktu kompilasi. catatan akhir
Untuk type_parameterT yang tidak diketahui sebagai jenis referensi (§15.2.5), konversi berikut yang melibatkan T dianggap sebagai konversi pembuka kotak (§10.3.7) pada waktu kompilasi. Pada run-time, jika T adalah jenis nilai, konversi dijalankan sebagai konversi unboxing. Pada run-time, jika T merupakan jenis referensi, konversi dijalankan sebagai konversi referensi eksplisit atau konversi identitas.
- Dari kelas
Cdasar yang efektif dariTkeTdan dari kelas dasar apa pun hinggaCT.Catatan: C akan menjadi salah satu jenis
System.Object, ,System.ValueTypeatauSystem.Enum(jika tidakT, akan diketahui sebagai jenis referensi). catatan akhir - Dari interface_type apa pun hingga
T.
yang T diketahui sebagai jenis referensi (§15.2.5), konversi eksplisit berikut ada:
- Dari
Tke interface_typebelum ada konversi implisit dariIkeT. Konversi ini terdiri dari konversi tinju implisit (§10.2.9) dariTkeobjectdiikuti dengan konversi referensi eksplisit dariobjectkeI. Pada run-time, jikaTadalah jenis nilai, konversi dijalankan sebagai konversi tinju diikuti dengan konversi referensi eksplisit. Pada run-time, jikaTmerupakan jenis referensi, konversi dijalankan sebagai konversi referensi eksplisit. - Dari parameter
Ujenis hinggaTyang disediakan tergantungTpadaU(§15.2.5). Pada run-time, jikaTadalah jenis nilai danUmerupakan jenis referensi, konversi dijalankan sebagai konversi unboxing. Pada run-time, jika danTUmerupakan jenis nilai, makaTdanUharus jenis yang sama dan tidak ada konversi yang dilakukan. Pada run-time, jikaTmerupakan jenis referensi, makaUtentu juga merupakan jenis referensi dan konversi dijalankan sebagai konversi referensi eksplisit atau konversi identitas.
Dalam semua kasus, aturan memastikan bahwa konversi dijalankan sebagai konversi unboxing jika dan hanya jika pada run-time konversi berasal dari jenis referensi ke jenis nilai.
Aturan di atas tidak mengizinkan konversi eksplisit langsung dari parameter jenis yang tidak dibatasi ke jenis non-antarmuka, yang mungkin mengejutkan. Alasan untuk aturan ini adalah untuk mencegah kebingungan dan membuat semantik konversi tersebut jelas.
Contoh: Pertimbangkan deklarasi berikut:
class X<T> { public static long F(T t) { return (long)t; // Error } }Jika konversi eksplisit langsung dari
tkelongdiizinkan, seseorang mungkin dengan mudah mengharapkan ituX<int>.F(7)akan mengembalikan7L. Namun, itu tidak akan, karena konversi numerik standar hanya dipertimbangkan ketika jenis diketahui numerik pada waktu pengikatan. Untuk memperjelas semantik, contoh di atas harus ditulis:class X<T> { public static long F(T t) { return (long)(object)t; // Ok, but will only work when T is long } }Kode ini sekarang akan dikompilasi tetapi mengeksekusi
X<int>.F(7)kemudian akan melemparkan pengecualian pada run-time, karena kotak tidak dapat dikonversiintlangsung kelong.contoh akhir
10.3.9 Konversi eksplisit yang ditentukan pengguna
Konversi eksplisit yang ditentukan pengguna terdiri dari konversi eksplisit standar opsional, diikuti dengan eksekusi operator konversi implisit atau eksplisit yang ditentukan pengguna, diikuti oleh konversi eksplisit standar opsional lainnya. Aturan yang tepat untuk mengevaluasi konversi eksplisit yang ditentukan pengguna dijelaskan dalam §10.5.5.
10.4 Konversi standar
10.4.1 Umum
Konversi standar adalah konversi yang telah ditentukan sebelumnya yang dapat terjadi sebagai bagian dari konversi yang ditentukan pengguna.
10.4.2 Konversi implisit Standar
Konversi implisit berikut diklasifikasikan sebagai konversi implisit standar:
- Konversi identitas (§10.2.2)
- Konversi numerik implisit (§10.2.3)
- Konversi implisit nullable (§10.2.6)
- Konversi harfiah null (§10.2.7)
- Konversi referensi implisit (§10.2.8)
- Konversi tinju (§10.2.9)
- Konversi ekspresi konstanta implisit (§10.2.11)
- Konversi implisit yang melibatkan parameter jenis (§10.2.12)
Konversi implisit standar secara khusus mengecualikan konversi implisit yang ditentukan pengguna.
10.4.3 Konversi eksplisit Standar
Konversi eksplisit standar adalah semua konversi implisit standar ditambah subset konversi eksplisit di mana konversi implisit standar yang berlawanan ada.
Catatan: Dengan kata lain, jika konversi implisit standar ada dari jenis
Ake jenisB, maka konversi eksplisit standar ada dari jenisAke jenisBdan dari jenis ke jenisBA. catatan akhir
10.5 Konversi yang ditentukan pengguna
10.5.1 Umum
C# memungkinkan konversi implisit dan eksplisit yang telah ditentukan sebelumnya untuk ditambah oleh konversi yang ditentukan pengguna. Konversi yang ditentukan pengguna diperkenalkan dengan mendeklarasikan operator konversi (§15.10.4) di kelas dan jenis struktur.
10.5.2 Konversi yang ditentukan pengguna yang diizinkan
C# hanya mengizinkan konversi tertentu yang ditentukan pengguna untuk dideklarasikan. Secara khusus, tidak mungkin untuk menentukan ulang konversi implisit atau eksplisit yang sudah ada.
Untuk jenis S sumber dan jenis Ttarget tertentu , jika S atau T jenis nilai nullable, biarkan S₀ dan T₀ lihat jenis yang mendasarnya, jika tidak S₀ dan T₀ sama dengan S dan T masing-masing. Kelas atau struktur diizinkan untuk mendeklarasikan konversi dari jenis sumber ke jenis ST target hanya jika semua hal berikut ini benar:
-
S₀danT₀merupakan jenis yang berbeda. - Baik
S₀atauT₀adalah kelas atau jenis struct tempat deklarasi operator berlangsung. - Tidak
S₀jugaT₀bukan interface_type. - Tidak termasuk konversi yang ditentukan pengguna, konversi tidak ada dari
SkeTatau dariTkeS.
Pembatasan yang berlaku untuk konversi yang ditentukan pengguna ditentukan dalam §15.10.4.
10.5.3 Evaluasi konversi yang ditentukan pengguna
Konversi yang ditentukan pengguna mengonversi ekspresi sumber, yang mungkin memiliki jenis sumber, ke jenis lain, yang disebut jenis target. Evaluasi pusat konversi yang ditentukan pengguna pada menemukan operator konversi yang ditentukan pengguna yang paling spesifik untuk ekspresi sumber dan jenis target. Penentuan ini dipecah menjadi beberapa langkah:
- Menemukan set kelas dan struktur tempat operator konversi yang ditentukan pengguna akan dipertimbangkan. Set ini terdiri dari jenis sumber dan kelas dasarnya, jika jenis sumber ada, bersama dengan jenis target dan kelas dasarnya. Untuk tujuan ini diasumsikan bahwa hanya kelas dan struktur yang dapat mendeklarasikan operator yang ditentukan pengguna, dan bahwa jenis non-kelas tidak memiliki kelas dasar. Selain itu, jika jenis sumber atau target adalah jenis nilai nullable, jenis yang mendasarnya digunakan sebagai gantinya.
- Dari kumpulan jenis tersebut, menentukan operator konversi yang ditentukan pengguna dan diangkat mana yang berlaku. Agar operator konversi berlaku, dimungkinkan untuk melakukan konversi standar (§10,4) dari ekspresi sumber ke jenis operand operator, dan dimungkinkan untuk melakukan konversi standar dari jenis hasil operator ke jenis target.
- Dari set operator yang ditentukan pengguna yang berlaku, menentukan operator mana yang tidak ambigu yang paling spesifik. Secara umum, operator yang paling spesifik adalah operator yang jenis operand-nya "paling dekat" dengan ekspresi sumber dan yang jenis hasilnya "paling dekat" dengan jenis target. Operator konversi yang ditentukan pengguna lebih disukai daripada operator konversi yang diangkat. Aturan yang tepat untuk menetapkan operator konversi yang ditentukan pengguna yang paling spesifik ditentukan ditentukan dalam subklaus berikut.
Setelah operator konversi yang ditentukan pengguna yang paling spesifik diidentifikasi, eksekusi aktual konversi yang ditentukan pengguna melibatkan hingga tiga langkah:
- Pertama, jika diperlukan, lakukan konversi standar dari ekspresi sumber ke jenis operand operator konversi yang ditentukan pengguna atau diangkat.
- Selanjutnya, panggil operator konversi yang ditentukan pengguna atau diangkat untuk melakukan konversi.
- Terakhir, jika diperlukan, melakukan konversi standar dari jenis hasil operator konversi yang ditentukan pengguna ke jenis target.
Evaluasi konversi yang ditentukan pengguna tidak pernah melibatkan lebih dari satu operator konversi yang ditentukan pengguna atau diangkat. Dengan kata lain, konversi dari jenis ke jenis ST tidak akan pernah terlebih dahulu menjalankan konversi yang ditentukan pengguna dari S ke X lalu menjalankan konversi yang ditentukan pengguna dari X ke T.
- Definisi yang tepat tentang evaluasi konversi implisit atau eksplisit yang ditentukan pengguna diberikan dalam subklaus berikut. Definisi menggunakan istilah-istilah berikut:
- Jika konversi implisit standar (§10.4.2) ada dari jenis
Ake jenisB, dan jika baikAmaupunBbukan interface_type, makaAdianggap termasuk dalamB, danBdianggap mencakupA. - Jika konversi implisit standar (§10,4,2) ada dari ekspresi
Eke jenisB, dan jika tidakBatau jenisE(jika memilikinya) interface_type, kemudianEdikatakan dilirik olehB, danBdikatakan kepada mencakupE. - Jenis yang paling mencakup dalam sekumpulan jenis adalah satu jenis yang mencakup semua jenis lain dalam set. Jika tidak ada jenis tunggal yang mencakup semua jenis lainnya, maka set tidak memiliki jenis yang paling mencakup. Dalam istilah yang lebih intuitif, jenis yang paling mencakup adalah jenis "terbesar" dalam set —satu jenis yang masing-masing jenisnya dapat dikonversi secara implisit.
- Jenis yang paling mencakup dalam sekumpulan jenis adalah satu jenis yang disertakan oleh semua jenis lain dalam set. Jika tidak ada jenis tunggal yang dililit oleh semua jenis lainnya, maka set tidak memiliki jenis yang paling dilirik. Dalam istilah yang lebih intuitif, jenis yang paling mencakup adalah jenis "terkecil" dalam set —satu jenis yang dapat dikonversi secara implisit ke masing-masing jenis lainnya.
10.5.4 Konversi implisit yang ditentukan pengguna
Konversi implisit yang ditentukan pengguna dari ekspresi E ke jenis T diproses sebagai berikut:
Tentukan jenis
S,S₀danT₀.- Jika
Ememiliki jenis, biarkanSjenis tersebut. - Jika
SatauTadalah jenis nilai nullable, biarkanSᵢdanTᵢmenjadi jenis yang mendasarnya, jika tidak, biarkanSᵢdanTᵢST, masing-masing. - Jika
SᵢatauTᵢmerupakan parameter jenis, biarkanS₀danT₀jadilah kelas dasar yang efektif, jika tidak, biarkanS₀danT₀SᵢTᵢ, masing-masing.
- Jika
Temukan sekumpulan jenis,
D, tempat operator konversi yang ditentukan pengguna akan dipertimbangkan. Set ini terdiri dariS₀(jikaS₀ada dan merupakan kelas atau struktur), kelasS₀dasar (jikaS₀ada dan merupakan kelas), danT₀(jikaT₀adalah kelas atau struktur). Jenis ditambahkan ke setDhanya jika konversi identitas ke jenis lain yang sudah disertakan dalam set tidak ada.Temukan kumpulan operator konversi yang ditentukan pengguna dan diangkat yang berlaku,
U. Set ini terdiri dari operator konversi implisit yang ditentukan pengguna dan diangkat yang dideklarasikan oleh kelas atau struktur dalamDkonversi tersebut dari jenis yang mencakupEke jenis yang dicakup olehT. JikaUkosong, konversi tidak terdefinisi dan terjadi kesalahan waktu kompilasi.Temukan jenis sumber yang paling spesifik,
Sₓ, dari operator diU:- Jika
Sada dan salah satu operator dalamUkonversi dariS, makaSₓadalahS. - Jika tidak,
Sₓadalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber operator diU. Jika tepat satu jenis yang paling lengkap tidak dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi.
- Jika
Temukan jenis target yang paling spesifik,
Tₓ, dari operator diU:- Jika salah satu operator dalam
Ukonversi keT, makaTₓadalahT. - Jika tidak,
Tₓadalah jenis yang paling mencakup dalam kumpulan gabungan jenis target operator diU. Jika tepat satu jenis yang paling mencakup tidak dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi.
- Jika salah satu operator dalam
Temukan operator konversi yang paling spesifik:
- Jika
Uberisi tepat satu operator konversi yang ditentukan pengguna yang dikonversi dariSₓkeTₓ, maka ini adalah operator konversi yang paling spesifik. - Jika tidak, jika
Uberisi tepat satu operator konversi yang diangkat yang dikonversi dariSₓkeTₓ, maka ini adalah operator konversi yang paling spesifik. - Jika tidak, konversi bersifat ambigu dan terjadi kesalahan waktu kompilasi.
- Jika
Terakhir, terapkan konversi:
- Jika E belum memiliki jenis
Sₓ, maka konversi implisit standar dariEkeSₓdilakukan. - Operator konversi yang paling spesifik dipanggil untuk mengonversi dari
SₓkeTₓ. - Jika
TₓtidakT, maka konversi implisit standar dariTₓkeTdilakukan.
- Jika E belum memiliki jenis
Konversi implisit yang ditentukan pengguna dari jenis S ke jenis T ada jika konversi implisit yang ditentukan pengguna ada dari variabel jenis S ke T.
10.5.5 Konversi eksplisit yang ditentukan pengguna
Konversi eksplisit yang ditentukan pengguna dari ekspresi E ke jenis T diproses sebagai berikut:
- Tentukan jenis
S,S₀danT₀.- Jika
Ememiliki jenis, biarkanSjenis tersebut. - Jika
SatauTadalah jenis nilai nullable, biarkanSᵢdanTᵢmenjadi jenis yang mendasarnya, jika tidak, biarkanSᵢdanTᵢST, masing-masing. - Jika
SᵢatauTᵢmerupakan parameter jenis, biarkanS₀danT₀jadilah kelas dasar yang efektif, jika tidak, biarkanS₀danT₀SᵢTᵢ, masing-masing.
- Jika
- Temukan sekumpulan jenis,
D, tempat operator konversi yang ditentukan pengguna akan dipertimbangkan. Set ini terdiri dariS₀(jikaS₀ada dan merupakan kelas atau struktur), kelasS₀dasar (jikaS₀ada dan merupakan kelas),T₀(jikaT₀adalah kelas atau struct), dan kelasT₀dasar (jikaT₀adalah kelas). Jenis ditambahkan ke setDhanya jika konversi identitas ke jenis lain yang sudah disertakan dalam set tidak ada. - Temukan kumpulan operator konversi yang ditentukan pengguna dan diangkat yang berlaku,
U. Set ini terdiri dari operator konversi implisit atau eksplisit yang ditentukan pengguna dan diangkat yang dideklarasikan oleh kelas atau struktur dalamDkonversi tersebut dari jenis yang mencakupEatau dicakup olehS(jika ada) ke jenis yang mencakup atau dicakup olehT. JikaUkosong, konversi tidak terdefinisi dan terjadi kesalahan waktu kompilasi. - Temukan jenis sumber yang paling spesifik,
Sₓ, dari operator diU:- Jika S ada dan salah satu operator dalam
Ukonversi dariS, makaSₓadalahS. - Jika tidak, jika salah satu operator dalam
Ukonversi dari jenis yang mencakupE, makaSₓadalah jenis yang paling terpusat dalam kumpulan gabungan jenis sumber operator tersebut. Jika tidak ada jenis yang paling lengkap yang dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi. - Jika tidak,
Sₓadalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber operator diU. Jika tepat satu jenis yang paling mencakup tidak dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi.
- Jika S ada dan salah satu operator dalam
- Temukan jenis target yang paling spesifik,
Tₓ, dari operator diU:- Jika salah satu operator dalam
Ukonversi keT, makaTₓadalahT. - Jika tidak, jika salah satu operator dalam
Ukonversi ke jenis yang disertakan olehT, makaTₓadalah jenis yang paling mencakup dalam kumpulan gabungan jenis target operator tersebut. Jika tepat satu jenis yang paling mencakup tidak dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi. - Jika tidak,
Tₓadalah jenis yang paling mencakup dalam kumpulan gabungan jenis target operator diU. Jika tidak ada jenis yang paling lengkap yang dapat ditemukan, maka konversi ambigu dan terjadi kesalahan waktu kompilasi.
- Jika salah satu operator dalam
- Temukan operator konversi yang paling spesifik:
- Jika U berisi tepat satu operator konversi yang ditentukan pengguna yang dikonversi dari
SₓkeTₓ, maka ini adalah operator konversi yang paling spesifik. - Jika tidak, jika
Uberisi tepat satu operator konversi yang diangkat yang dikonversi dariSₓkeTₓ, maka ini adalah operator konversi yang paling spesifik. - Jika tidak, konversi bersifat ambigu dan terjadi kesalahan waktu kompilasi.
- Jika U berisi tepat satu operator konversi yang ditentukan pengguna yang dikonversi dari
- Terakhir, terapkan konversi:
- Jika
Ebelum memiliki jenisSₓ, maka konversi eksplisit standar dari E keSₓdilakukan. - Operator konversi yang ditentukan pengguna yang paling spesifik dipanggil untuk mengonversi dari
SₓkeTₓ. - Jika
TₓtidakT, maka konversi eksplisit standar dariTₓkeTdilakukan.
- Jika
Konversi eksplisit yang ditentukan pengguna dari jenis S ke jenis T ada jika konversi eksplisit yang ditentukan pengguna ada dari variabel jenis S ke T.
10.6 Konversi yang melibatkan jenis nullable
10.6.1 Konversi Nullable
Konversi nullable memungkinkan konversi yang telah ditentukan sebelumnya yang beroperasi pada jenis nilai yang tidak dapat diubah ke null untuk juga digunakan dengan bentuk nullable dari jenis tersebut. Untuk setiap konversi implisit atau eksplisit yang telah ditentukan sebelumnya yang mengonversi dari jenis nilai yang tidak dapat diubah ke jenis STnilai yang tidak dapat diubah ke null (§10.2.2, §10.2.3, §10.2.4, §10.2.11, §10.3.2 dan §10.3.3), konversi nullable berikut ada:
- Konversi implisit atau eksplisit dari
S?keT? - Konversi implisit atau eksplisit dari
SkeT? - Konversi eksplisit dari
S?keT.
Konversi nullable itu sendiri diklasifikasikan sebagai konversi implisit atau eksplisit.
Konversi nullable tertentu diklasifikasikan sebagai konversi standar dan dapat terjadi sebagai bagian dari konversi yang ditentukan pengguna. Secara khusus, semua konversi nullable implisit diklasifikasikan sebagai konversi implisit standar (§10.4.2), dan konversi eksplisit nullable yang memenuhi persyaratan §10.4.3 diklasifikasikan sebagai konversi eksplisit standar.
Evaluasi konversi nullable berdasarkan konversi yang mendasar dari S ke T melanjutkan sebagai berikut:
- Jika konversi nullable adalah dari
S?keT?:- Jika nilai sumber null (
HasValueproperti adalahfalse), hasilnya adalah nilai null dari jenisT?. - Jika tidak, konversi dievaluasi sebagai pembungkusan dari
S?keS, diikuti oleh konversi yang mendasar dariSkeT, diikuti dengan pembungkusan dariTkeT?.
- Jika nilai sumber null (
- Jika konversi nullable adalah dari
SkeT?, konversi dievaluasi sebagai konversi yang mendasar dariSmenjadiTdiikuti dengan pembungkusan dariTkeT?. - Jika konversi nullable adalah dari
S?keT, konversi dievaluasi sebagai unwrapping dariS?keSdiikuti dengan konversi yang mendasar dariSkeT.
10.6.2 Konversi yang diangkat
Mengingat operator konversi yang ditentukan pengguna yang mengonversi dari jenis nilai yang tidak dapat diubah ke jenis S nilai yang tidak dapat diubah ke null, T konversi yang diangkat ada yang mengonversi dari ke S?.T? Operator konversi yang diangkat ini melakukan pembungkusan dari S? ke S diikuti oleh konversi yang ditentukan pengguna dari S ke T diikuti dengan pembungkusan dari T ke T?, kecuali bahwa nilai S? null dikonversi langsung ke nilai T?null . Operator konversi yang diangkat memiliki klasifikasi implisit atau eksplisit yang sama dengan operator konversi yang mendasar yang ditentukan pengguna.
10.7 Konversi fungsi anonim
10.7.1 Umum
Anonymous_method_expression atau lambda_expression diklasifikasikan sebagai fungsi anonim (§12.21). Ekspresi tidak memiliki jenis, tetapi dapat dikonversi secara implisit ke jenis delegasi yang kompatibel. Beberapa ekspresi lambda juga dapat dikonversi secara implisit ke jenis pohon ekspresi yang kompatibel.
Secara khusus, fungsi F anonim kompatibel dengan jenis D delegasi yang disediakan:
- Jika
Fberisi anonymous_function_signature, makaDdanFmemiliki jumlah parameter yang sama. - Jika
Ftidak berisi anonymous_function_signature, makaDmungkin memiliki parameter nol atau lebih dari jenis apa pun, selama tidak ada parameterDyang merupakan parameter output. - Jika
Fmemiliki daftar parameter yang ditik secara eksplisit, setiap parameter diDmemiliki pengubah yang sama dengan parameter yang sesuai di dan konversi identitas ada diFantara parameter yang sesuai diF. - Jika
Fmemiliki daftar parameter yang ditik secara implisit,Dtidak memiliki parameter referensi atau output. - Jika isi
Fadalah ekspresi , danDmemiliki jenis pengembalian yang batal atauFasinkron danDmemiliki«TaskType»jenis pengembalian (§15.14.1), maka ketika setiap parameterFdiberikan jenis parameter yang sesuai diD, isinyaFadalah ekspresi yang valid (w.r.t §12) yang akan diizinkan sebagai statement_expression (§13.7). - Jika isi
Fadalah blok, danDmemiliki jenis pengembalian yang batal atauFasinkron danDmemiliki«TaskType»jenis pengembalian , maka ketika setiap parameterFdiberikan jenis parameter yang sesuai diD, isinyaFadalah blok yang valid (w.r.t §13.3) di mana tidak adareturnpernyataan yang menentukan ekspresi. - Jika isi
Fadalah ekspresi, dan baikFtidak asinkron danDmemiliki jenis pengembalian non-voidT, atauFasinkron danDmemiliki jenis pengembalian«TaskType»<T>(§15.14.1), maka ketika setiap parameterFdiberi tipe yang sesuai dengan parameter diD, isiFadalah ekspresi yang valid (w.r.t §12) yang secara implisit dapat dikonversi keT. - Jika isi
Fadalah blok, dan tidakFasinkron danDmemiliki jenisTpengembalian non-void , asinkron danFmemilikiDjenis pengembalian, maka ketika setiap parameter«TaskType»<T>diberikan jenis parameter yang sesuai diF, isinyaDadalah blok pernyataan yang valid (w.r.tF) dengan titik akhir yang tidak dapat dijangkau di mana setiap pernyataan pengembalian menentukan ekspresi yang secara implisit dapat dikonversi ke .
Contoh: Contoh berikut mengilustrasikan aturan ini:
delegate void D(int x); D d1 = delegate { }; // Ok D d2 = delegate() { }; // Error, signature mismatch D d3 = delegate(long x) { }; // Error, signature mismatch D d4 = delegate(int x) { }; // Ok D d5 = delegate(int x) { return; }; // Ok D d6 = delegate(int x) { return x; }; // Error, return type mismatch delegate void E(out int x); E e1 = delegate { }; // Error, E has an output parameter E e2 = delegate(out int x) { x = 1; }; // Ok E e3 = delegate(ref int x) { x = 1; }; // Error, signature mismatch delegate int P(params int[] a); P p1 = delegate { }; // Error, end of block reachable P p2 = delegate { return; }; // Error, return type mismatch P p3 = delegate { return 1; }; // Ok P p4 = delegate { return "Hello"; }; // Error, return type mismatch P p5 = delegate(int[] a) // Ok { return a[0]; }; P p6 = delegate(params int[] a) // Error, params modifier { return a[0]; }; P p7 = delegate(int[] a) // Error, return type mismatch { if (a.Length > 0) return a[0]; return "Hello"; }; delegate object Q(params int[] a); Q q1 = delegate(int[] a) // Ok { if (a.Length > 0) return a[0]; return "Hello"; };contoh akhir
Contoh: Contoh berikut menggunakan jenis
Func<A,R>delegasi generik yang mewakili fungsi yang mengambil argumen jenisAdan mengembalikan nilai jenisR:delegate R Func<A,R>(A arg);Dalam penugasan
Func<int,int> f1 = x => x + 1; // Ok Func<int,double> f2 = x => x + 1; // Ok Func<double,int> f3 = x => x + 1; // Error Func<int, Task<int>> f4 = async x => x + 1; // Okparameter dan jenis pengembalian dari setiap fungsi anonim ditentukan dari jenis variabel tempat fungsi anonim ditetapkan.
Penugasan pertama berhasil mengonversi fungsi anonim ke jenis
Func<int,int>delegasi karena, ketikaxdiberikan jenisint,x + 1adalah ekspresi valid yang secara implisit dapat dikonversi ke jenisint.Demikian juga, penetapan kedua berhasil mengonversi fungsi anonim ke jenis delegasi Func<int, ganda> karena hasil
x + 1(dari jenisint) secara implisit dapat dikonversi ke jenisdouble.Namun, penugasan ketiga adalah kesalahan waktu kompilasi karena, ketika
xdiberikan jenisdouble, hasilx + 1(dari jenisdouble) tidak secara implisit dapat dikonversi ke jenisint.Penugasan keempat berhasil mengonversi fungsi asinkron anonim ke jenis
Func<int, Task<int>>delegasi karena hasilx + 1(dari jenisint) secara implisit dapat dikonversi ke jenisintpengembalian efektif dari asinkron lambda, yang memiliki jenisTask<int>pengembalian .contoh akhir
Ekspresi F lambda kompatibel dengan jenis Expression<D> pohon ekspresi jika F kompatibel dengan jenis Ddelegasi . Ini tidak berlaku untuk metode anonim, hanya ekspresi lambda.
Fungsi anonim dapat memengaruhi resolusi kelebihan beban, dan berpartisipasi dalam inferensi jenis. Lihat §12.6 untuk detail lebih lanjut.
10.7.2 Evaluasi konversi fungsi anonim ke jenis delegasi
Konversi fungsi anonim ke jenis delegasi menghasilkan instans delegasi yang mereferensikan fungsi anonim dan set (mungkin kosong) dari variabel luar yang ditangkap yang aktif pada saat evaluasi. Ketika delegasi dipanggil, isi fungsi anonim dijalankan. Kode dalam isi dijalankan menggunakan sekumpulan variabel luar yang ditangkap yang direferensikan oleh delegasi. delegate_creation_expression (§12.8.17.5) dapat digunakan sebagai sintaks alternatif untuk mengonversi metode anonim ke jenis delegasi.
Daftar pemanggilan delegasi yang dihasilkan dari fungsi anonim berisi satu entri. Objek target yang tepat dan metode target delegasi tidak ditentukan. Secara khusus, tidak ditentukan apakah objek target delegasi adalah null, this nilai anggota fungsi penutup, atau beberapa objek lainnya.
Konversi fungsi anonim yang identik secara semantik dengan kumpulan instans variabel luar yang ditangkap (mungkin kosong) yang sama ke jenis delegasi yang sama diizinkan (tetapi tidak diperlukan) untuk mengembalikan instans delegasi yang sama. Istilah yang identik secara semantik digunakan di sini untuk berarti bahwa eksekusi fungsi anonim akan, dalam semua kasus, menghasilkan efek yang sama mengingat argumen yang sama. Aturan ini mengizinkan kode seperti berikut ini untuk dioptimalkan.
delegate double Function(double x);
class Test
{
static double[] Apply(double[] a, Function f)
{
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++)
{
result[i] = f(a[i]);
}
return result;
}
static void F(double[] a, double[] b)
{
a = Apply(a, (double x) => Math.Sin(x));
b = Apply(b, (double y) => Math.Sin(y));
...
}
}
Karena dua delegasi fungsi anonim memiliki kumpulan variabel luar yang ditangkap (kosong) yang sama, dan karena fungsi anonim secara semantik identik, kompilator diizinkan untuk meminta delegasi merujuk ke metode target yang sama. Kompilator diizinkan untuk mengembalikan instans delegasi yang sama persis dari kedua ekspresi fungsi anonim.
10.7.3 Evaluasi konversi ekspresi lambda ke jenis pohon ekspresi
Konversi ekspresi lambda ke jenis pohon ekspresi menghasilkan pohon ekspresi (§8,6). Lebih tepatnya, evaluasi konversi ekspresi lambda menghasilkan struktur objek yang mewakili struktur ekspresi lambda itu sendiri.
Tidak setiap ekspresi lambda dapat dikonversi ke jenis pohon ekspresi. Konversi ke jenis delegasi yang kompatibel selalu ada, tetapi mungkin gagal pada waktu kompilasi karena alasan yang ditentukan implementasi.
Catatan: Alasan umum untuk ekspresi lambda gagal dikonversi ke jenis pohon ekspresi meliputi:
- Ini memiliki badan blok
- Ini memiliki pengubah
async- Ini berisi operator penugasan
- Ini berisi parameter output atau referensi
- Ini berisi ekspresi yang terikat secara dinamis
catatan akhir
10.8 Konversi grup metode
Konversi implisit ada dari grup metode (§12,2) ke jenis delegasi yang kompatibel (§21,4). Jika D adalah jenis delegasi, dan E merupakan ekspresi yang diklasifikasikan sebagai grup metode, maka D kompatibel dengan E jika dan hanya jika E berisi setidaknya satu metode yang berlaku dalam bentuk normalnya (§12.6.4.2) ke daftar argumen apa pun (§12.6.2) memiliki jenis dan pengubah yang cocok dengan jenis parameter dan pengubah D, seperti yang dijelaskan dalam hal berikut.
Aplikasi waktu kompilasi konversi dari grup E metode ke jenis D delegasi dijelaskan dalam hal berikut.
- Metode tunggal
Mdipilih sesuai dengan pemanggilan metode (§12.8.10.2) formulirE(A), dengan modifikasi berikut:- Daftar
Aargumen adalah daftar ekspresi, masing-masing diklasifikasikan sebagai variabel dan dengan jenis dan pengubah (in,out, atauref) dari parameter yang sesuai dalam — kecuali parameter jenisD, di mana ekspresi yang sesuai memiliki jenisdynamicalih-alihobject. - Metode kandidat yang dipertimbangkan hanya metode yang berlaku dalam bentuk normalnya dan tidak menghilangkan parameter opsional apa pun (§12.6.4.2). Dengan demikian, metode kandidat diabaikan jika hanya berlaku dalam bentuk yang diperluas, atau jika satu atau beberapa parameter opsional mereka tidak memiliki parameter yang sesuai di
D.
- Daftar
- Konversi dianggap ada jika algoritma §12.8.10.2 menghasilkan satu metode
Mterbaik yang kompatibel (§21,4) denganD. - Jika metode
Myang dipilih adalah metode instans, ekspresi instans yang terkait denganEmenentukan objek target delegasi. - Jika metode
Myang dipilih adalah metode ekstensi yang ditandai dengan akses anggota pada ekspresi instans, ekspresi instans tersebut menentukan objek target delegasi. - Hasil konversi adalah nilai jenis
D, yaitu delegasi yang mengacu pada metode yang dipilih dan objek target.
Contoh: Berikut ini menunjukkan konversi grup metode:
delegate string D1(object o); delegate object D2(string s); delegate object D3(); delegate string D4(object o, params object[] a); delegate string D5(int i); class Test { static string F(object o) {...} static void G() { D1 d1 = F; // Ok D2 d2 = F; // Ok D3 d3 = F; // Error – not applicable D4 d4 = F; // Error – not applicable in normal form D5 d5 = F; // Error – applicable but not compatible } }Penugasan untuk
d1secara implisit mengonversi grupFmetode menjadi nilai jenisD1.Penugasan untuk
d2menunjukkan bagaimana mungkin untuk membuat delegasi ke metode yang memiliki jenis parameter yang kurang diturunkan (kontravarian) dan jenis pengembalian yang lebih turunan (kovarian).Penugasan untuk
d3menunjukkan bagaimana tidak ada konversi jika metode tidak berlaku.Penugasan untuk
d4menunjukkan bagaimana metode harus berlaku dalam bentuk normalnya.Penugasan untuk
d5menunjukkan bagaimana parameter dan jenis pengembalian delegasi dan metode diizinkan untuk berbeda hanya untuk jenis referensi.contoh akhir
Seperti halnya semua konversi implisit dan eksplisit lainnya, operator cast dapat digunakan untuk melakukan konversi tertentu secara eksplisit.
Contoh: Dengan demikian, contoh
object obj = new EventHandler(myDialog.OkClick);dapat ditulis sebagai gantinya
object obj = (EventHandler)myDialog.OkClick;contoh akhir
Konversi grup metode dapat merujuk ke metode generik, baik dengan secara eksplisit menentukan argumen jenis dalam E, atau melalui inferensi jenis (§12.6.3). Jika inferensi jenis digunakan, jenis parameter delegasi digunakan sebagai jenis argumen dalam proses inferensi. Jenis pengembalian delegasi tidak digunakan untuk inferensi. Apakah argumen jenis ditentukan atau disimpulkan, argumen tersebut adalah bagian dari proses konversi grup metode; ini adalah argumen jenis yang digunakan untuk memanggil metode target ketika delegasi yang dihasilkan dipanggil.
Contoh:
delegate int D(string s, int i); delegate int E(); class X { public static T F<T>(string s, T t) {...} public static T G<T>() {...} static void Main() { D d1 = F<int>; // Ok, type argument given explicitly D d2 = F; // Ok, int inferred as type argument E e1 = G<int>; // Ok, type argument given explicitly E e2 = G; // Error, cannot infer from return type } }contoh akhir
Grup metode dapat memengaruhi resolusi kelebihan beban, dan berpartisipasi dalam inferensi jenis. Lihat §12.6 untuk detail lebih lanjut.
Evaluasi run-time dari konversi grup metode berlanjut sebagai berikut:
- Jika metode yang dipilih pada waktu kompilasi adalah metode instans, atau merupakan metode ekstensi yang diakses sebagai metode instans, objek target delegasi ditentukan dari ekspresi instans yang terkait dengan
E:- Ekspresi instans dievaluasi. Jika evaluasi ini menyebabkan pengecualian, tidak ada langkah lebih lanjut yang dijalankan.
- Jika ekspresi instans adalah reference_type, nilai yang dihitung oleh ekspresi instans menjadi objek target. Jika metode yang dipilih adalah metode instans dan objek target adalah
null,System.NullReferenceExceptionakan dilemparkan dan tidak ada langkah lebih lanjut yang dijalankan. - Jika ekspresi instans adalah value_type, operasi tinju (§10.2.9) dilakukan untuk mengonversi nilai menjadi objek, dan objek ini menjadi objek target.
- Jika tidak, metode yang dipilih adalah bagian dari panggilan metode statis, dan objek target delegasi adalah
null. - Instans delegasi jenis
Ddelegasi diperoleh dengan referensi ke metode yang ditentukan pada waktu kompilasi dan referensi ke objek target yang dihitung di atas, sebagai berikut:- Konversi diizinkan (tetapi tidak diperlukan) untuk menggunakan instans delegasi yang ada yang sudah berisi referensi ini.
- Jika instans yang ada tidak digunakan kembali, instans baru dibuat (§21,5). Jika tidak ada cukup memori yang tersedia untuk mengalokasikan instans baru, akan
System.OutOfMemoryExceptiondilemparkan. Jika tidak, instans diinisialisasi dengan referensi yang diberikan.
ECMA C# draft specification