#c# #vb.net #type-safety
#c# #vb.net #безопасность типов
Вопрос:
Вчера я был на собеседовании, где мой интервьюер (который, по общему признанию, не претендовал на звание эксперта по этому вопросу) заявил, что «VB.NET более слабо типизирован, чем C #» — (В то же время он не смог вспомнить пример).
Это утверждение показалось мне некорректным (особенно учитывая, что оба языка используют одни и те же библиотеки фреймворка для своих типов), и я посоветовал как таковой и что, возможно, его смутила опция включения / выключения Option Strict или Option Infer.
В то же время я знаю, что VB.NET имеет ситуации, когда он будет выполнять принудительное ввод типов, что иногда приводит к неожиданным результатам (хотя я также не могу вспомнить, при каких условиях) — (На самом деле, я думаю, я только что вспомнил, что это было в основном при выполнении арифметических операций с разными типами, тогда как другие языки заставят вас быть явным (?)).
Итак, не мог бы кто-нибудь, пожалуйста, уточнить, является ли VB.NET как-то более слабо типизирован, чем C #, и если да, то не могли бы вы привести примеры?
Комментарии:
1. Не существует такого понятия, как слабо типизированный, вы есть или вас нет
2. Я давно не использовал VB, и когда я это делал, у меня всегда был
Option Explicit
включен; но разве эта опция все еще не существует?3. Также … просто выкидываю это туда; мы действительно говорим «строго типизированный», или вы имеете в виду «статически типизированный»?
4. @Lavinski — Я бы не согласился, что он такой же черно-белый, как вы утверждаете, и @Andrew Barber Option Strict включает Option Explicit вместе с рядом других проверок.
5. Нет, слабо, мы знаем, что он статически типизирован. Я думаю, что он имел в виду больше случаи, когда типы вели себя неожиданно в различных условиях — в любом случае, таково было мое мнение об этом.
Ответ №1:
«Слабо типизированный» и «строго типизированный» фактически бессмысленны без уточнения. То, как они используются, обычно означает «система типов имеет функции, которые мне не нравятся» или «система типов имеет функции, которые мне нравятся». Похоже, что ваш интервьюер не имеет четкого представления о том, что означают эти термины, и поэтому, вероятно, не должен задавать вопросы о них в интервью.
Существует множество особенностей систем типов, которые разные люди называют «строго типизированными» по сравнению со «слабо типизированными». Например, некоторые люди говорят, что «строго типизированный» означает «каждый объект знает свой собственный тип во время выполнения». Некоторые люди говорят, что «строго типизированный» означает, что компилятор знает точный тип каждой переменной и выражения. Некоторые люди говорят, что это означает, что компилятор имеет неточные ограничения типа для каждой переменной и выражения. И так далее. Каждая особенность систем типов может считаться указывающей на «сильный».
Я предлагаю отказаться от всего необоснованного понятия «сильной» и «слабой» типизации и поговорить о том, что вы на самом деле имеете в виду.
Различия между системами типов C # и VB невелики, особенно после добавления ‘dynamic’ в C # 4.0. И C #, и VB используют систему типов CLR, в которой каждый объект знает свой собственный тип и в которой незаконные преобразования типов обнаруживаются средой выполнения (либо при выполнении кода, либо при его передаче через верификатор) и превращаются в исключения. Оба имеют одиночное наследование для классов и множественное наследование для интерфейсов. Оба делают различие между типами значений и ссылочными типами. И так далее.
Принципиальное различие между системами типов C # и VB заключается в том, что VB поддерживает необязательное сокращение времени статической проверки типов во время компиляции и откладывание проверки типов до времени выполнения, что больше похоже на язык с динамически типизированным интерфейсом. Это очень удобно при взаимодействии с объектными моделями, которые были разработаны для систем динамического типа. Мы добавили аналогичную функцию в C # 4.0, но в соответствии с исторической поддержкой статической типизации в C # 4.0 эта функция основана на статическом вводе определенных выражений как «динамических», которые затем разрешаются путем повторного запуска анализатора типов во время выполнения и выполнения анализа типов для живых объектов.
Больше на эту тему можно найти в моем блоге:
http://ericlippert.com/2012/10/15/is-c-a-strongly-typed-or-a-weakly-typed-language/
Комментарии:
1. Потрясающе получить ответ от самого человека! Спасибо. PS: Можете ли вы, пожалуйста, заставить Using() {} работать для нескольких типов без взломов? Довольно, пожалуйста! :-p
2. @Maxim — Что не так с
using(var obj1 = new obj1) using(var obj2 = new obj2){ obj1.Thing = obj2.Stuff(); }
3. Я считаю, что такой же взлом, как использование ((IDisposable obj1), (obj2)) {} — просто выглядит или ощущается неправильно..
4. То, что я напечатал — каждый
using
в отдельной строке, конечно, красиво, аккуратно и компактно. Или вы один из тех людей, которые думают, что инструкции должны быть «короткими», просто ради краткости? 😉5. лол, ой, ну нет, но если бы я хотел быть подробным, я бы вернулся к VB. 🙂
Ответ №2:
В качестве стратегии собеседования было бы лучше сказать «вы правы, он более слабо типизирован, но только для определенных настроек, таких как опция Strict Off или Опция Infer off»
Большинству людей приятнее, когда им говорят «вы правы», а не «вы запутались» 🙂
Комментарии:
1. лол, хотя я понимаю твою точку зрения, мне не интересно работать на кого-то, кто не может выносить критику или дебаты. К счастью, у меня есть роскошь текущей оплачиваемой работы.
Ответ №3:
(Я никогда раньше не использовал VB, так что для меня это тоже в новинку)
Они ссылаются на инструкцию Option Strict, или, скорее, на то, что происходит, когда вы ее опускаете.
Следующий VB компилируется и выполняется идеально до тех пор, пока у вас есть Option Explicit
выключенный:
Class Widget
Sub Method1()
End Sub
End Class
Sub Main()
Dim someInt As Integer
Dim someDouble As Double
Dim someObj As Object = New Widget
someDouble = 1234567890.9876542
someInt = someDouble
Call someObj.Method1()
Call someObj.Method2() ' causes runtime error
End Sub
Приведенное выше неявно преобразует double в целое число, вызывает метод Method1
по Object
ссылке и даже вызывает метод Method2
(который даже не существует) — ни один из которых не будет компилироваться в C # или в VB с Option Strict On
.
Это определенно соответствует определению «не такой строго типизированный«, как C #, хотя термин кажется довольно субъективным.
Обновление: Мы можем использовать ILSpy, чтобы раскрыть происходящее здесь «волшебство», посмотрев на скомпилированную сборку (на C #):
object obj = new Module1.Widget();
double num = 1234567890.9876542;
int i = Math.Round(num);
NewLateBinding.LateCall(obj, null, "Method1", new object[0], null, null, null, true);
NewLateBinding.LateCall(obj, null, "Method2", new object[0], null, null, null, true);
Это объясняет, почему VB.Net compiler способен делать вещи, которые в противном случае казались бы незаконными в среде CLR, хотя, похоже, это приводит к некоторому снижению производительности во время выполнения.
Ответ №4:
VB.NET допускает оба варианта. Как упоминалось в комментариях, вы можете установить это в проекте (или файле), установив Option Strict
либо ВКЛ., либо ВЫКЛ.
В документации MSDN здесь немного подробнее рассказывается о том, что делает этот параметр.