Я думаю, что этот сценарий лучше всего суммирует, почему DirectCast имеет ложное представление о безопасности проверки типов во время компиляции для типа, не являющегося объектом (ключевое слово объекта), и просто предназначен для возврата на место.
float f = 10;
long l = f;
Option Strict On
Dim f As Single = 10
Dim l As Long = f
Кодировщик C #, обнаружив, что float не может быть напрямую назначен на long и не будет компилироваться, сделает следующее:
long l = (long)f;
Что правильно.
Теперь давайте обратимся к нашему кодировщику VB.NET, обнаружив, что float не может быть назначен на long и не будет компилироваться, попробуем следующее:
Dim l As Long = DirectCast(f, Long)
Через несколько секунд ...
Программист VB.NET: Пожалуйста, позвольте мне сделать мои ставки, пожалуйста, скомпилируйте, пожалуйста ... !!!
Спустя некоторое время после просмотра Googling-fu и MSDN:
Программист VB.NET: А ... так что я должен использовать эту конструкцию CLng или CType для приведения переменных
Dim l As Long = CLng(f)
Это то, что я имел в виду, когда DirectCast имел ложное представление о безопасности проверки типов во время компиляции. DirectCast просто предназначены для возврата, если программист не знает, когда и где их следует использовать. DirectCast - это защитное одеяло, которое нельзя носить постоянно.
Насколько полезен DirectCast в этом сценарии, если он все-таки не будет использоваться?
[РЕДАКТИРОВАТЬ]
@Jules
Я не утверждаю, что все программисты VB.NET не знают, как на самом деле использовать DirectCast. Некоторые из них действительно знают, что DirectCast предназначен только для использования только для типов объектов (и примитивных типов, заключенных в объект).
Один из сценариев, в котором кодировщик VB.NET, перекодирующий существующий код C # в VB.NET, придет к неверному выводу, связан с ожидаемой (правильно это или нет) симметрией языков по отношению друг к другу.
Когда он видит в коде эту конструкцию ...
TextBox txt = (TextBox)sender;
... Он / она переведет это на следующее:
Dim txt As TextBox = DirectCast(sender, TextBox)
Что правильно.
Теперь, поскольку мы, программисты, любим симметрию, некоторые из нас (я мог бы быть тоже, если не знаю CLng) будут стремиться преобразовать этот код ...
/* Numbers are stored in file as float(component's file structure
is designed by 3rd party company) */
float f = file.ReadFloat(0);
long l = (long)f; // But we don't care about using the fractional part
...к этому:
Dim f As Single = file.ReadFloat(0)
Dim l As Long = DirectCast(f, Long)
Если человек C # - это тот, кто конвертирует код C # в VB.NET, он будет разочарован очевидным отсутствием симметрии здесь.
Но для человека VB.NET, которому поручено преобразовать код C # в VB.NET, у него сложится впечатление, что компилятор C # не улавливает несовместимые присвоения типов, в то время как VB.NET улавливает его. Теперь, за это очевидное открытие, я хочу похвастаться этой особенностью VB.NET перед своими коллегами и на некоторых форумах.
Но чтобы программист VB.NET не ошибся, неверно определив назначение первого кода. Фрагмент кода C # выше начал свою жизнь так. изначально был написан так:
float f = file.ReadFloat(0);
long l = f;
И это не будет компилироваться, компилятор C # улавливает несовместимые присвоения типов в том же духе, что эквивалентный VB.NET с Option Strict On
также не будет компилировать это (хотя не будет компилироваться только тогда, когда Option Strict
установлено в On
, слишком снисходительный). Итак, нам нужно привести тип float к long, используя (long)
. Становится так: long l = (long)f;
Теперь для преобразования одного типа переменной в другой совместимый тип в том же ключе, в котором мы преобразовываем этот код ...
TextBox txt = (TextBox)sender;
... к этому коду:
Dim txt As TextBox = DirectCast(sender, Textbox)
Мы должны преобразовать этот код ...
long l = (long)f; // Will compile
... к этому коду:
Dim l As Long = DirectCast(f, Long) ' Will not compile
Но, увы, это не компилируется. При приведении типов между совместимыми примитивными типами DirectCast проигрывает. Он не предлагает никакой симметрии по сравнению с приведенным выше кодом C # и не может использоваться для преобразования совместимых примитивных типов, несмотря на его название Direct Cast b >.
На мой взгляд, DirectCast следует называть CastObject, поскольку в любом случае он может выполнять приведение только между типами объектов (а также примитивными типами, заключенными в объект). DirectCast действительно не занимается присвоением совместимых примитивных типов (целочисленные, двойные, а также их младшие и высшие аналоги). При назначении между совместимыми примитивными типами DirectCast перестает быть полезным, особенно если вы все равно вернете его назад и замените правильным.
Или, как мне кажется, конструкция DirectCast должна быть изменена, чтобы она могла приводить совместимые типы, как старые и новые языки с тех пор, например, C, C ++, C #, Java, Delphi, D и т. Д. когда дело доходит до приведения типов, он предлагает значительную симметрию VB.NET по сравнению с другими языками. Поступая так, мы также можем выбросить (только гипотетически, мы не можем заставить другие программы отказываться, которые полагаются на старые функции) все множество функций, имена которых напрямую не сопоставляются с их типами (например, CInt, CDbl, CSng и т. Д.) . Мы просто будем использовать DirectCast вместо них.
person
Michael Buen
schedule
21.04.2010
string s = "10"; int i = (int)s;
не компилируется на C #. - person Robert Davis   schedule 21.04.2010int i = (int)d;
может выполнять известное преобразование для известного типа, как в вашем примере кода, в любом сценарии, где вы реалистично использовали быDirectCast
в VB.NET (т. Е. Когда тип объекта неизвестен при компиляции time), приведение с()
в C # не выполняет преобразование - оно просто выполняет приведение. Таким образом, двойное число в штучной упаковке не может быть распаковано как целое число. По этой причине они фактически эквивалентны. - person Dan Tao   schedule 21.04.2010System.Type
методIsAssignableFrom
. - person Michael Petito   schedule 22.04.2010()
отличается отDirectCast
, верны для типов значений, но неверны для типов ссылочных. [Эти два эквивалента для ссылочных типов; преобразование не выполняется.] Это делает сравнение бессмысленным, потому что, IMHO, нет причин использоватьDirectCast
с типом value. Как я это вижу:()
эквивалентноCType
для типов значений иDirectCast
для ссылочных типов. - person ToolmakerSteve   schedule 18.04.2018