DirectCast () ve VB.NET'te CType () arasındaki fark


99

VB.NET'e yeni giren deneyimli bir C / C ++ / C # programcısıyım. Genelde yayınlar için CType (ve CInt, CBool, CStr) kullanıyorum çünkü bu daha az karakter içeriyor ve maruz kaldığım ilk döküm yöntemiydi, ancak DirectCast ve TryCast'ın da farkındayım.

Basitçe, DirectCast ve CType arasında herhangi bir fark (dönüştürme etkisi, performans, vb.) Var mı? TryCast fikrini anlıyorum.


6
DirectCast, CType, TryCast ile bu Casting DataType'ın tam kopyası stackoverflow.com/questions/2703585/…
MarkJ

Yanıtlar:


182

Dikkat edilmesi gereken ilk şey, VB.NET'in C # 'ın (type)instanceçevrim mekanizmasına doğrudan bir analoğu olmamasıdır . Bunu gündeme getiriyorum çünkü iki VB.NET operatörünü karşılaştırmak için bir başlangıç ​​noktası olarak yararlıdır (ve bunlar operatörlerdir, fonksiyon anlamlarına sahip olsalar bile fonksiyon değillerdir).

DirectCast()C # döküm operatöründen daha katıdır. Yalnızca, zaten döküm yaptığınız öğe zaten yayınladığınız tür olduğunda yayınlamanıza izin verir. Yine de değer türlerinin kutusundan çıkarılacağına inanıyorum, ancak aksi takdirde herhangi bir dönüştürme yapmaz. Yani, örneğin, yayın yapamazsanız shortiçin intbir C # ile olabilir gibi (int)döküm. Ancak IEnumerable, temeldeki IEnumerablenesne değişkeniniz gerçekten bir Array. Ve elbette Object, nesne örneğinizin türünün, miras ağacında gerçekten cast türünüzün altında bir yerde olduğunu varsayarak, herhangi bir şeyden dönüştürme yapabilirsiniz .

Bu arzu edilir çünkü çok daha hızlıdır . Gerçekleştirilmesi gereken daha az dönüştürme ve tür denetimi vardır.

CType()C # döküm operatöründen daha az katıdır. (int)Bir dizeyi tam sayıya dönüştürmek gibi basit tarzda bir atamayla yapamayacağınız şeyleri yapacak . Oyuncunuzun hedef türü olan Convert.To___()C # ' da arama kadar güce sahiptir ___.

Bu arzu edilir çünkü çok güçlüdür. Ancak bu güç, performans pahasına gelir; DirectCast()ya da C # 'ın cast operatörü kadar hızlı değil çünkü atmayı bitirmek için epeyce iş yapması gerekebilir. Genel olarak DirectCast(), yapabildiğiniz zamanları tercih etmelisiniz .

Son olarak, TryCast()C # asoperatörünün doğrudan analogu olan bir döküm operatörünü kaçırdınız .


23
+1 Katılığının DirectCastbaşka bir avantaj olduğunu söyleyebilirim . Bir hata yaparsanız, derleyici size hemen söyler, ancak CTypebir hata ile çalışma zamanında ara sıra yanlış davranışlara neden olabilir - belki farklı bölgesel ayarlara sahip bazı kullanıcı makinelerinde.
MarkJ

1
Mükemmel cevap. Yani karmaşıklık amacıyla (küçük büyüğe doğru): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()doğru olacaktır?
sloganı

3
@motto - kapat. C <xyz> () "işlevleri", işlev anlamsallığına sahip olsalar bile, işlevlerden ziyade operatörler oldukları için listede daha üst sıralara taşınmalıdır. Bunlara sahip olan türler için, C # 'ın (tür) dönüşümüne çok yakındırlar, ancak biraz daha fazla iş yapacaklardır.
Joel Coehoorn

3
Yorumunuz için @MarkJ +1, ancak not DirectCastyalnızca sınıflarda katıdır, arabirimlerle değil (çünkü .NET Türü .GetInterfaceslistesi tarafından tanımlanmayan arabirimleri gerçekten uygulayan COM türlerine ve belki de başkalarına sahip olabilirsiniz ).
Mark Hurd

2
@JoelCoehoorn +1, Ama aslında TryCast()ve astam olarak aynı değiller. TryCast()yalnızca referans türleriyle asçalışır, boş olabilecek herhangi bir şeyle çalışır. Yani int? icast = myNum as int?;gayet iyi çalışacak, ancak Dim icast as Integer? = TryCast(myNum, Integer?)bir derleyici hatası verecektir. İki dil arasında sadece bir tuhaf fark daha var. lol
CptRobby

12

İle CTypebunun gibi bir şey yazabilirsiniz Ctype("string",Integer). Ancak DirectCastyukarıdaki ifade ile derleme zamanı hatası verir.

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

0

DirectCastdaha kısıtlayıcıdır CType.

Örneğin, bu bir hata verecektir:

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

Ayrıca Visual Studio IDE'de de gösterilecektir.

Ancak bu, bir hata oluşturmaz:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.