Разница между DirectCast () и CType () в VB.NET


100

Я опытный программист на C / C ++ / C #, который только что вошел в VB.NET. Я обычно использую CType (и CInt, CBool, CStr) для приведения типов, потому что это меньше символов и это был первый способ приведения, с которым я столкнулся, но я также знаю DirectCast и TryCast.

Просто есть ли различия (эффект приведения, производительность и т. Д.) Между DirectCast и CType? Я понимаю идею TryCast.


6
Точный дубликат этого кастинга типов данных с DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ

1
Возможный дубликат Кастинг Datatypes с DirectCast, CType, TryCast
Имад

Ответы:


183

Прежде всего следует отметить, что VB.NET не имеет прямого аналога (type)instanceмеханизму приведения типов в C # . Я поднимаю этот вопрос, потому что он полезен в качестве отправной точки при сравнении двух операторов VB.NET (и это операторы, а не функции, хотя они имеют семантику функций).

DirectCast()является более строгим, чем оператор приведения в C #. Он позволяет выполнять приведение только в том случае, если приводимый элемент уже является типом, к которому выполняется приведение. Я считаю, что он все равно будет распаковывать типы значений, но в противном случае он не будет выполнять никакого преобразования. Так, например, вы не можете shortвыполнить приведение из в int, как это было бы при приведении C # (int). Но вы можете преобразовать IEnumerableего в массив, если ваша базовая IEnumerableпеременная объекта действительно является Array. И, конечно же, вы можете выполнять приведение Objectк чему угодно, при условии, что тип вашего экземпляра объекта действительно находится где-то ниже вашего типа приведения в дереве наследования.

Это желательно, потому что это намного быстрее . Требуется меньше преобразований и проверки типов.

CType()менее строг, чем оператор приведения в C #. Он будет делать то, что вы просто не можете сделать с помощью простого (int)приведения, например, преобразовывать строку в целое число. Он имеет столько же возможностей, сколько вызов Convert.To___()в C #, где ___это целевой тип вашего приведения.

Это желательно, потому что оно очень мощное. Однако эта мощность достигается за счет производительности; он не такой быстрый, как DirectCast()оператор приведения в C # или, потому что для завершения приведения может потребоваться довольно много работы. Как правило, вы должны предпочесть, DirectCast()когда можете.

Наконец, вы пропустили один оператор приведения:, TryCast()который является прямым аналогом asоператора C # .


24
+1 Я бы сказал, что строгость DirectCast- еще одно преимущество. Если вы допустили ошибку, компилятор немедленно сообщит вам об этом, но CTypeошибка может вызвать случайное неправильное поведение во время выполнения - возможно, на какой-то пользовательской машине с другими региональными настройками.
MarkJ

1
Отличный ответ. Таким образом , в порядке сложности (мала до велика) DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()было бы правильно?
девиз

3
@motto - закрыть. «Функции» C <xyz> () следует переместить выше в списке, поскольку они на самом деле являются операторами, а не функциями, даже если они имеют семантику функций. Для тех типов, у которых они есть, они очень близки к приведению (типу) в C #, но сделают немного больше.
Джоэл Коэхорн

3
@MarkJ +1 для вашего комментария, но примечание DirectCastстрого относится только к классам, а не интерфейсам (потому что у вас могут быть типы COM - и, возможно, другие - которые фактически реализуют интерфейсы, не определенные в .GetInterfacesсписке типов .NET ).
Марк Херд

2
@JoelCoehoorn +1, но на самом деле TryCast()и asне совсем то. TryCast()работает только со ссылочными типами, а asработает со всем, что может быть нулевым. Так int? icast = myNum as int?;будет работать нормально, но Dim icast as Integer? = TryCast(myNum, Integer?)компилятор выдаст ошибку. Еще одно своеобразное различие между двумя языками. lol
CptRobby

12

С помощью CTypeвы можете написать что-нибудь вроде этого Ctype("string",Integer). Но с DirectCastприведенным выше заявлением будет ошибка времени компиляции.

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

0

DirectCastболее строгий, чем CType.

Например, это вызовет ошибку:

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

Он также будет показан в IDE Visual Studio.

Однако это не вызывает ошибки:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.