Różnica między DirectCast () i CType () w VB.NET


99

Jestem doświadczonym programistą C / C ++ / C #, który właśnie dostał się do VB.NET. Generalnie używam CType (i CInt, CBool, CStr) do rzutów, ponieważ jest to mniej znaków i był to pierwszy sposób rzucania, na który byłem narażony, ale jestem również świadomy DirectCast i TryCast.

Po prostu, czy są jakieś różnice (efekt rzucania, wydajność itp.) Między DirectCast i CType? Rozumiem ideę TryCast.


6
Dokładny duplikat tego Casting DataTypes z DirectCast, CType, TryCast stackoverflow.com/questions/2703585/ ...
MarkJ

Odpowiedzi:


182

Pierwszą rzeczą, na którą należy zwrócić uwagę, jest to, że VB.NET nie ma bezpośredniego odpowiednika (type)instancemechanizmu rzutowania języka C # . Podnoszę to, ponieważ jest to przydatne jako punkt wyjścia do porównania dwóch operatorów VB.NET (i są one operatorami, a nie funkcjami, mimo że mają semantykę funkcji).

DirectCast()jest bardziej rygorystyczny niż operator rzutowania C #. Pozwala na rzucanie tylko wtedy, gdy rzucany przedmiot jest typem, do którego rzucasz. Uważam, że nadal będzie rozpakowywać typy wartości, ale w przeciwnym razie nie dokona żadnej konwersji. Na przykład nie można rzutować z shortdo int, tak jak w przypadku (int)rzutowania w języku C # . Ale można rzutować z IEnumerabletablicy an do tablicy, jeśli podstawową IEnumerablezmienną obiektu naprawdę jest Array. Oczywiście możesz rzutować z Objectdo wszystkiego, zakładając, że typ instancji obiektu naprawdę znajduje się gdzieś poniżej typu rzutowania w drzewie dziedziczenia.

Jest to pożądane, ponieważ jest znacznie szybsze . Jest mniej konwersji i sprawdzania typów, które muszą mieć miejsce.

CType()jest mniej rygorystyczny niż operator rzutowania C #. Będzie robić rzeczy, których po prostu nie można zrobić z (int)rzutowaniem prostym , na przykład przekonwertować łańcuch na liczbę całkowitą. Ma taką samą moc, jak wywołanie Convert.To___()w języku C #, gdzie ___jest docelowym typem rzutowania.

Jest to pożądane, ponieważ jest bardzo potężne. Jednak ta moc odbywa się kosztem wydajności; nie jest tak szybki jak DirectCast()operator rzutowania w języku C #, ponieważ może wymagać sporo pracy, aby zakończyć rzutowanie. Generalnie wolisz, DirectCast()kiedy możesz.

Wreszcie przegapiłeś jeden operator rzutowania:, TryCast()który jest bezpośrednim analogiem do asoperatora C # .


23
+1 Powiedziałbym, że surowość DirectCastto kolejna zaleta. Jeśli popełnisz błąd, kompilator natychmiast poinformuje Cię o tym, ale CTypepomyłka może spowodować sporadyczne nieprawidłowe zachowanie w czasie wykonywania - na przykład na komputerze użytkownika z różnymi ustawieniami regionalnymi.
MarkJ

1
Świetna odpowiedź. Aby więc złożoności (małe i duże) DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()byłoby prawidłowe?
motto

3
@motto - zamknij. „Funkcje” C <xyz> () należy przesunąć wyżej na liście, ponieważ w rzeczywistości są one operatorami, a nie funkcjami, nawet jeśli mają semantykę funkcji. W przypadku tych typów, które je mają, są one bardzo zbliżone do rzutowania C # (typu), ale wykonają tylko trochę więcej pracy.
Joel Coehoorn

3
@MarkJ +1 dla twojego komentarza, ale uwaga DirectCastjest ścisła tylko w przypadku klas, a nie interfejsów (ponieważ możesz mieć typy COM - i być może inne - które faktycznie implementują interfejsy nie zdefiniowane na liście .NET Type .GetInterfaces).
Mark Hurd,

2
@JoelCoehoorn +1, Ale w rzeczywistości TryCast()i asnie są dokładnie takie same. TryCast()działa tylko z typami referencyjnymi, podczas gdy asdziała z wszystkim, co może mieć wartość null. Więc int? icast = myNum as int?;będzie działać dobrze, ale Dim icast as Integer? = TryCast(myNum, Integer?)spowoduje błąd kompilatora. Jeszcze jedna osobliwa różnica między tymi dwoma językami. lol
CptRobby,

12

Z CTypetobą możesz napisać coś takiego Ctype("string",Integer). Ale z DirectCastpowyższym stwierdzeniem dałoby błąd czasu kompilacji.

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

0

DirectCastjest bardziej restrykcyjne niż CType.

Na przykład spowoduje to wyświetlenie błędu:

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

Zostanie również wyświetlony w środowisku IDE programu Visual Studio.

To jednak nie powoduje błędu:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.