Pertimbangkan kode berikut:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
Apa perbedaan antara ketiga jenis casting (oke, yang ketiga bukan casting, tetapi Anda mendapatkan maksudnya). Yang mana yang lebih disukai?
string s = Convert.ToString(o)
:; 5:string s = $"{o}"
(atau setara denganstring.Format
formulir untuk C # sebelumnya)Jawaban:
Melemparkan InvalidCastException jika
o
bukanstring
. Jika tidak, tetapkano
untuks
, bahkan jikao
adanull
.Wakilnya
null
untuks
jikao
tidakstring
atau jikao
ininull
. Karena alasan ini, Anda tidak dapat menggunakannya dengan tipe nilai (operator tidak akan pernah bisa kembalinull
dalam kasus itu). Jika tidak, tetapkano
kes
.Menyebabkan NullReferenceException jika
o
adalahnull
. Tetapkan apa pun yango.ToString()
dikembalikans
, apa pun jenisnyao
.Gunakan 1 untuk sebagian besar konversi - sederhana dan mudah. Saya cenderung hampir tidak pernah menggunakan 2 karena jika ada sesuatu yang bukan tipe yang tepat, saya biasanya mengharapkan pengecualian terjadi. Saya hanya melihat perlunya jenis fungsionalitas return-null ini dengan pustaka yang dirancang dengan buruk yang menggunakan kode kesalahan (mis. Return null = error, alih-alih menggunakan pengecualian).
3 bukan pemain dan hanya doa metode. Gunakan untuk ketika Anda membutuhkan representasi string dari objek non-string.
sumber
string s = (string)o;
Gunakan ketika sesuatu pasti menjadi hal lain.string s = o as string;
Gunakan ketika sesuatu mungkin menjadi hal lain.string s = o.ToString();
Gunakan ketika Anda tidak peduli apa itu tetapi Anda hanya ingin menggunakan representasi string yang tersedia.sumber
Itu benar-benar tergantung pada apakah Anda tahu apakah
o
itu string dan apa yang ingin Anda lakukan dengannya. Jika komentar Andao
benar-benar benar-benar string, saya lebih suka yang lurus(string)o
- itu tidak mungkin gagal.Keuntungan terbesar menggunakan straight cast adalah ketika gagal, Anda mendapatkan InvalidCastException , yang memberi tahu Anda apa yang salah.
Dengan
as
operator, jikao
bukan string,s
diatur kenull
, yang berguna jika Anda tidak yakin dan ingin mengujis
:Namun, jika Anda tidak melakukan tes itu, Anda akan menggunakannya
s
nanti dan melempar NullReferenceException . Ini cenderung lebih umum dan jauh lebih sulit untuk dilacak begitu mereka terjadi di alam liar, karena hampir setiap baris referensi variabel dan mungkin melemparkan satu. Di sisi lain, jika Anda mencoba melakukan cast ke tipe nilai (primitif, atau struct seperti DateTime ), Anda harus menggunakan cast langsung - yangas
tidak akan berfungsi.Dalam kasus khusus konversi ke string, setiap objek memiliki
ToString
, jadi metode ketiga Anda mungkin baik-baik saja jikao
tidak nol dan Anda berpikirToString
metode tersebut dapat melakukan apa yang Anda inginkan.sumber
as
dengan nullable jenis nilai. IEo as DateTime
tidak akan bekerja, tetapio as DateTime?
akan ...if (s is string)
saja?is
ing, Anda harus melakukan cast lagi, jadi Anda memiliki is dan kemudian cast yang keras. Untuk beberapa alasan,as
cek dan nol terasa lebih baik bagi saya.Jika Anda sudah tahu tipe apa yang bisa dilemparkan, gunakan pemeran gaya-C:
Perhatikan bahwa hanya dengan pemeran gaya C yang dapat Anda lakukan pemaksaan tipe eksplisit.
Jika Anda tidak tahu apakah itu tipe yang diinginkan dan Anda akan menggunakannya jika ya, gunakan sebagai kata kunci:
Perhatikan bahwa karena tidak akan memanggil operator konversi tipe apa pun. Ini hanya akan menjadi non-null jika objek tersebut tidak nol dan asli dari jenis yang ditentukan.
Gunakan ToString () untuk mendapatkan representasi string yang dapat dibaca manusia dari objek apa pun, bahkan jika itu tidak dapat dilemparkan ke string.
sumber
Kata kunci as bagus di asp.net saat Anda menggunakan metode FindControl.
Ini berarti Anda dapat beroperasi pada variabel yang diketik daripada harus membuangnya
object
seperti yang Anda lakukan dengan pemain langsung:Ini bukan hal yang besar, tetapi menghemat baris kode dan penugasan variabel, plus lebih mudah dibaca
sumber
'as' didasarkan pada 'is', yang merupakan kata kunci yang memeriksa saat runtime jika objek tersebut kompatibel secara polimorfik (pada dasarnya jika para pemain dapat dibuat) dan mengembalikan nol jika pemeriksaan gagal.
Keduanya setara:
Menggunakan 'sebagai':
Menggunakan 'is':
Sebaliknya, para pemeran c-style juga dibuat pada saat runtime, tetapi melemparkan pengecualian jika pemeran tidak dapat dibuat.
Hanya untuk menambahkan fakta penting:
Kata kunci 'sebagai' hanya berfungsi dengan jenis referensi. Anda tidak dapat melakukan:
Dalam hal ini Anda harus menggunakan casting.
sumber
2 berguna untuk casting ke tipe turunan.
Misalkan a adalah Hewan:
akan mendapatkan sebuah makan dengan minimal gips.
sumber
Menurut eksperimen yang dijalankan pada halaman ini: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(halaman ini terkadang memiliki beberapa kesalahan "pengarah ilegal" yang muncul, jadi segarkan jika ada)
Kesimpulannya adalah, operator "sebagai" biasanya lebih cepat daripada pemain. Kadang-kadang lebih cepat, kadang-kadang hanya lebih cepat.
Saya pribadi "sebagai" juga lebih mudah dibaca.
Jadi, karena lebih cepat dan "lebih aman" (tidak akan membuang pengecualian), dan mungkin lebih mudah dibaca, saya sarankan menggunakan "sebagai" sepanjang waktu.
sumber
"(string) o" akan menghasilkan InvalidCastException karena tidak ada pemeran langsung.
"o as string" akan menghasilkan menjadi referensi nol, bukan pengecualian yang dilemparkan.
"o.ToString ()" bukan gips dalam bentuk apa pun, ini adalah metode yang diimplementasikan oleh objek, dan dengan demikian dalam satu atau lain cara, oleh setiap kelas di .net yang "melakukan sesuatu" dengan contoh dari kelas yang dipanggil dan mengembalikan sebuah string.
Jangan lupa bahwa untuk mengkonversi ke string, ada juga Convert.ToString (someType instanceOfThatType) di mana someType adalah salah satu dari serangkaian jenis, pada dasarnya kerangka jenis dasar.
sumber
Semua jawaban yang diberikan baik, jika saya dapat menambahkan sesuatu: Untuk langsung menggunakan metode dan properti string (misalnya ToLower) Anda tidak dapat menulis:
Anda hanya bisa menulis:
tetapi Anda bisa menulis sebagai gantinya:
The
as
pilihan adalah lebih mudah dibaca (setidaknya untuk pendapat saya).sumber
(o as string).ToLower()
alih-alih beberapa tanda kurung yang membingungkan.Lebih disukai, karena menghindari penalti kinerja casting ganda.
sumber
Tampaknya keduanya secara konsep berbeda.
Casting langsung
Jenis tidak harus terkait erat. Muncul dalam semua jenis rasa.
Rasanya seperti objek akan dikonversi menjadi sesuatu yang lain.
SEBAGAI operator
Tipe memiliki hubungan langsung. Seperti dalam:
Rasanya seperti Anda akan menangani objek dengan cara yang berbeda.
Sampel dan IL
sumber
Saya ingin menarik perhatian pada spesifikasi operator sebagai berikut :
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
sumber
Ketika mencoba untuk mendapatkan representasi string dari apa pun (dari jenis apa pun) yang berpotensi menjadi nol, saya lebih suka baris kode di bawah ini. Ini kompak, itu memanggil ToString (), dan itu benar menangani nulls. Jika o adalah nol, s akan berisi String.Empty.
sumber
Karena tidak ada yang menyebutkannya, yang terdekat dengan instanceOf ke Jawa dengan kata kunci adalah ini:
sumber
Gunakan pemeran langsung
string s = (string) o;
jika dalam konteks logis aplikasi Andastring
adalah satu-satunya jenis yang valid. Dengan pendekatan ini, Anda akan mendapatkanInvalidCastException
dan menerapkan prinsip Gagal-cepat . Logika Anda akan dilindungi dari meneruskan jenis yang tidak valid lebih lanjut atau mendapatkan NullReferenceException jika digunakanas
operator.Jika logika mengharapkan beberapa tipe dilemparkan
string s = o as string;
dan periksanull
atau gunakanis
operator.Fitur keren baru telah muncul di C # 7.0 untuk menyederhanakan pemain dan memeriksa apakah Pencocokan Pola :
sumber
Dua bentuk konversi tipe (casting) berikut ini didukung dalam C #:
|
(CV
• Konversi tipe statis v ke c dalam ekspresi yang diberikan
• Hanya mungkin jika tipe dinamis dari v adalah c, atau subtipe dari c
• Jika tidak, InvalidCastException dilemparkan
|
v sebagai C
• Varian non-fatal dari (c) v
• Jadi, konversi tipe statis v ke c dalam ekspresi yang diberikan
• Mengembalikan nol jika tipe dinamis v bukan c, atau subtipe dari c
sumber