Perbedaan antara DirectCast () dan CType () di VB.NET

99

Saya seorang programmer C / C ++ / C # berpengalaman yang baru saja masuk ke VB.NET. Saya biasanya menggunakan CType (dan CInt, CBool, CStr) untuk cast karena karakternya lebih sedikit dan merupakan cara casting pertama yang saya alami, tetapi saya juga mengetahui DirectCast dan TryCast.

Sederhananya, apakah ada perbedaan (efek pemeran, kinerja, dll.) Antara DirectCast dan CType? Saya memahami ide TryCast.

Caleb Hearth
sumber
6
Duplikat yang tepat dari Casting DataTypes ini dengan DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ

Jawaban:

182

Hal pertama yang perlu diperhatikan adalah VB.NET tidak memiliki analog langsung ke (type)instancemekanisme casting C # . Saya mengemukakan ini karena berguna sebagai titik awal dalam membandingkan dua operator VB.NET (dan mereka adalah operator, bukan fungsi, meskipun mereka memiliki semantik fungsi).

DirectCast()lebih ketat daripada operator casting C #. Ini hanya memungkinkan Anda untuk melakukan cast ketika item yang sedang ditransmisikan adalah jenis yang Anda transmisikan. Saya yakin ini akan tetap membuka kotak jenis nilai, tetapi sebaliknya tidak akan melakukan konversi apa pun. Jadi, misalnya, Anda tidak dapat melakukan cast dari shortke int, seperti yang dapat Anda lakukan dengan (int)cast C # . Tapi Anda bisa mentransmisikan dari sebuah IEnumerableke sebuah array, jika IEnumerablevariabel objek Anda benar-benar adalah sebuah Array. Dan tentu saja Anda dapat melakukan cast dari Objectke apa pun, dengan asumsi jenis instance objek Anda benar-benar berada di bawah jenis cast Anda di pohon warisan.

Ini diinginkan karena jauh lebih cepat . Ada lebih sedikit konversi dan pemeriksaan jenis yang perlu dilakukan.

CType()tidak seketat operator casting C #. Ini akan melakukan hal-hal yang tidak dapat Anda lakukan dengan (int)cast bergaya sederhana , seperti mengubah string menjadi integer. Ini memiliki kekuatan yang sama dengan memanggil Convert.To___()di C #, di mana ___tipe target pemain Anda.

Ini diinginkan karena sangat kuat. Namun, kekuatan ini datang dengan mengorbankan kinerja; itu tidak secepat DirectCast()atau operator cor C # karena mungkin perlu melakukan banyak pekerjaan untuk menyelesaikan pemeran. Umumnya Anda harus memilih DirectCast()saat Anda bisa.

Akhirnya, Anda melewatkan satu operator casting:, TryCast()yang merupakan analog langsung ke asoperator C # .

Joel Coehoorn
sumber
23
+1 Menurut saya ketatnya DirectCastadalah keuntungan lain. Jika Anda membuat kesalahan, compiler akan segera memberi tahu Anda, tetapi dengan CTypekesalahan mungkin saja menyebabkan perilaku yang salah pada waktu proses - mungkin pada beberapa mesin pengguna dengan pengaturan regional yang berbeda.
MarkJ
1
Jawaban yang bagus. Jadi agar kompleksitas (kecil ke besar): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()akan benar?
motto
3
@ motto - tutup. C <xyz> () "functions" harus dipindahkan lebih tinggi pada daftar, karena mereka sebenarnya adalah operator daripada fungsi, meskipun mereka memiliki semantik fungsi. Untuk tipe yang memilikinya, mereka sangat dekat dengan casting C # (tipe), tapi hanya akan melakukan sedikit pekerjaan lagi.
Joel Coehoorn
3
@MarkJ +1 untuk komentar Anda, tetapi perhatikan DirectCasthanya ketat untuk kelas, bukan antarmuka (karena Anda dapat memiliki jenis COM - dan mungkin yang lain - yang benar-benar mengimplementasikan antarmuka yang tidak ditentukan oleh daftar Jenis .NET .GetInterfaces).
Mark Hurd
2
@JoelCoehoorn +1, Tapi sebenarnya, TryCast()dan astidak persis sama. TryCast()hanya bekerja dengan tipe referensi, sementara asbekerja dengan apapun yang bisa nol. Jadi int? icast = myNum as int?;akan bekerja dengan baik, tetapi Dim icast as Integer? = TryCast(myNum, Integer?)akan memberikan kesalahan kompiler. Hanya satu lagi perbedaan aneh antara kedua bahasa tersebut. lol
CptRobby
12

Dengan CTypeAnda dapat menulis sesuatu seperti ini Ctype("string",Integer). Tetapi dengan DirectCastpernyataan di atas akan memberikan kesalahan waktu kompilasi.

 Dim a As Integer = DirectCast("1", Integer) 'Gives compiler error
 Dim b As Integer = CType("1", Integer) 'Will compile
Abhay
sumber
0

DirectCastlebih ketat daripada CType.

Misalnya, ini akan memunculkan kesalahan:

Sub Main()
    Dim newint As Integer = DirectCast(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub

Ini juga akan ditampilkan di Visual Studio IDE.

Namun, ini tidak menimbulkan kesalahan:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Hemantha
sumber