Різниця між DirectCast () і CType () у VB.NET


99

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

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


6
Точний дублікат цього лиття Datatypes з DirectCast, CType, TryCast stackoverflow.com/questions/2703585 / ...
MarkJ

Відповіді:


182

Перше, що слід зазначити, 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 # .


23
+1 Я б сказав, що суворість DirectCast- ще одна перевага. Якщо ви помилитесь, компілятор повідомляє вам негайно, але з CTypeпомилкою просто може викликати випадкові неправильні поведінки під час виконання - можливо, на деякій користувацькій машині з різними регіональними налаштуваннями.
MarkJ

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

3
@motto - закрити. "Функції" C <xyz> () слід перемістити вище в списку, оскільки вони насправді є операторами, а не функціями, хоча вони мають семантику функцій. Для тих типів, які їх мають, вони дуже близькі до кастингу (типу) C #, але зроблять лише трохи більше роботи.
Joel Coehoorn

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

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

Він також буде показаний у ID Visual Studio IDE.

Однак це не призводить до помилки:

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.