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

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

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

Ответ 1

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

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

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

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

Как правило, вы можете предпочесть DirectCast(), когда сможете.

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

Ответ 2

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

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

Ответ 3

DirectCast намного ограничительнее, чем CType. Например,

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

вызывает ошибку. он также отображается в IDE визуальной студии. Но

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

Не выдает ошибку.