Действительно ли VB нечувствителен к регистру?

Я не пытаюсь начинать здесь спор, но по какой-то причине обычно утверждается, что Visual Basic нечувствителен к регистру, а языки C - нет (и почему-то это хорошо).

Но вот мой вопрос: где именно Visual Basic нечувствителен к регистру? Когда я печатаю ...

Dim ss As String
Dim SS As String

... в Visual Studio 2008 или Visual Studio 2010 IDE, у второго есть предупреждение:" Локальная переменная SS уже объявлена ​​в текущем блоке ". В VBA VBE он не сразу выдает ошибку, а просто автоматически исправляет случай.

Я что-то упускаю из-за этого аргумента, что Visual Basic не чувствителен к регистру? (Кроме того, если вы знаете или хотите ответить, почему это должно быть плохо?)

Почему я вообще задаю этот вопрос?

Я уже много лет использую Visual Basic во многих его диалектах, иногда как любитель, иногда для программ малого бизнеса в рабочей группе. Последние шесть месяцев я работал над большим проектом, намного большим, чем я ожидал. Большая часть примеров исходного кода написана на C #. У меня нет горячего желания изучать C #, но если есть вещи, которые я упускаю из того, что предлагает C #, чего нет в Visual Basic (противоположным будет VB.NET предлагает XML Literals), то я хотел бы узнать больше об этой функции. В этом случае часто утверждают, что языки C чувствительны к регистру, и это хорошо, а Visual Basic нечувствителен к регистру, а это плохо. Я хотел бы знать...

  1. Как именно Visual Basic нечувствителен к регистру, поскольку каждый пример в редакторе кода становится чувствительным к регистру (то есть регистр исправляется), хочу я этого или нет.
  2. Достаточно ли это убедительно для меня, чтобы подумать о переходе на C #, если случай VB.NET каким-то образом ограничивает то, что я могу делать с кодом?

person Todd Main    schedule 20.02.2010    source источник
comment
+1 Я задумывался о том же самом раньше.   -  person NakedBrunch    schedule 20.02.2010
comment
Эммм ... не уверен, что вы понимаете, что означает регистр- in. Поскольку VB фактически нечувствителен к регистру, SS и ss имеют одно и то же имя, тогда как в C они не будут.   -  person Ed S.    schedule 20.02.2010
comment
@ed: Я не могу использовать одновременно SS и ss в VB, в зависимости от того, что я использую первым, тот же, что и в редакторе.   -  person Todd Main    schedule 20.02.2010
comment
Отаку, я определенно рекомендую сосредоточить этот вопрос на том, что именно означает, что VB нечувствителен к регистру и как это реализовано. К сожалению, вопрос о том, лучше ли делать язык нечувствительным к регистру, может вызвать войну пламени. Если вам действительно интересно, задайте другой вопрос. (Я советую вам не делать этого, но если вы должны пометить это как субъективное и сделать это вики сообщества)   -  person MarkJ    schedule 22.02.2010
comment
@MarkJ - да, я тебя слышу. На вопрос о том, является ли это чувствительным к регистру, был решительный ответ, и это то, что я действительно искал. Что касается того, почему чувствительность / нечувствительность лучше / хуже, я пытался выяснить, есть ли точное техническое преимущество, например, чипы x386 быстрее, чем чипы x286, но похоже, что нет технической причины ( который был предоставлен), поэтому я не думаю, что на второй вопрос можно было бы ответить.   -  person Todd Main    schedule 22.02.2010
comment
Вы думали (или думали) об этом с ног на голову. Именно потому, что компилятор нечувствителен к регистру, ошибка считывает "переменную SS уже объявленную". Если бы он был чувствителен к регистру, вы бы получили либо «переменная ss не используется», либо вообще без ошибки и ошибку, если бы вы использовали поочередно то и другое.   -  person Adriano Varoli Piazza    schedule 15.03.2010
comment
Интересный момент, Андриано, я так не думал.   -  person Todd Main    schedule 15.03.2010
comment
Я думаю, что вы не осознавали, что VB нечувствителен к регистру. Это не похоже на многие другие популярные языки (например, C ++, C #, Java и т. Д.), Поэтому ss - это то же самое, что SS для компилятора.   -  person Cam    schedule 26.03.2010
comment
@incrediman: да, похоже, это среда IDE делает это только для одного случая, а компилятору все равно.   -  person Todd Main    schedule 26.03.2010


Ответы (14)


Разница между VBA и VB.NET заключается только в том, что VB.NET постоянно компилируется в фоновом режиме. . Вы получите сообщение об ошибке при компиляции VBA.

Как Джонатан говорит, при программировании вы можете думать о VB.NET как о без учета регистра, кроме сравнения строк, XML и некоторых других ситуаций ...

Я думаю, вам интересно, что находится под капотом. Что ж, .NET Common Language Runtime чувствителен к регистру, а код VB.NET полагается на среду выполнения, поэтому вы можете видеть, что он должен быть чувствительным к регистру во время выполнения, например когда он ищет переменные и методы.

Компилятор и редактор VB.NET позволяют вам игнорировать это, потому что они исправляют регистр в вашем коде.

Если вы поиграете с динамическими функциями или поздним связыванием (Option Strict Off), вы можете доказать, что базовая среда выполнения чувствительна к регистру. Другой способ увидеть это - понять, что языки с учетом регистра, такие как C #, используют одну и ту же среду выполнения, поэтому среда выполнения, очевидно, поддерживает чувствительность к регистру.

ИЗМЕНИТЬ. Если вы хотите исключить среду IDE из уравнения, вы всегда можете скомпилировать из командной строки. Отредактируйте свой код в Блокноте, чтобы в нем были ss и SS, и посмотрите, что делает компилятор. .

ИЗМЕНИТЬ Цитата из Джеффри Рихтера в . Рекомендации по проектированию .NET Framework стр. 45.

Чтобы было ясно, CLR действительно чувствительна к регистру. Некоторые языки программирования, например Visual Basic, нечувствительны к регистру. Когда компилятор Visual Basic пытается разрешить вызов метода для типа, определенного на языке с учетом регистра, таком как C #, компилятор (а не среда CLR) определяет фактический регистр имени метода и встраивает его в метаданные. CLR ничего об этом не знает. Теперь, если вы используете отражение для привязки к методу, API отражения действительно предлагают возможность выполнять поиск без учета регистра. Это степень нечувствительности к регистру в CLR.

person MarkJ    schedule 20.02.2010
comment
Лучший ответ, который я слышал до сих пор. Есть ли способ доказать, что компилятор и редактор VB.Net позволяют вам игнорировать это? Есть ли способ как нибудь отключить автокоррекцию? Или есть способ скомпилировать sln, который не написан в VS IDE в MSBuild, который использует как ss, так и SS, и будет компилироваться и работать должным образом? - person Todd Main; 20.02.2010
comment
Вы можете отключить автокоррекцию, обманув читателя. Щелкните правой кнопкой мыши файл vb и выберите «Открыть с помощью». Затем выберите что-нибудь вроде редактора XML (Text). Вы потеряете все специфические для VB функции, такие как автокоррекция. - person Jonathan Allen; 20.02.2010
comment
+1 отличный ответ, а также хороший вопрос, Отаку (я думаю, вы уже знали, но хотели вытянуть хорошее определение, эй?) - person Anonymous Type; 21.01.2011
comment
Компилятор / IDE VB.NET не на 100% нечувствителен к регистру. Например Dim pdfWriter As PDFWriter полностью действителен. VB.NET позволяет различать имена классов и имена переменных, что приятно, поскольку это обычная практика для языков, полностью чувствительных к регистру. - person ingredient_15939; 10.10.2013
comment
Путь VB подходит для взаимодействия. Пример: создайте DLL на C # с адресом электронной почты в виде String и Email () в качестве свойства с событием inotifypropertychanged в нем. C # будет компилироваться нормально, и будет сгенерирована DLL. Попробуйте сослаться на эту DLL на VB или другом подобном языке. Он скажет, что есть конфликт в переменной электронной почты / электронной почты в библиотеке. Инструменты анализа кода указывают на это как на проблему в компиляторе C #, а не в компиляторе VB. - person Venkat; 06.02.2019

Отчасти проблема здесь в том, что вам нужно отделить язык от опыта IDE.

Как язык, VB.NET, безусловно, нечувствителен к регистру в идентификаторах. Вызов DateTime.Parse и datetime.parse будет привязан к одному и тому же коду. И в отличие от таких языков, как C #, невозможно определить методы или типы, которые различаются только регистром.

В качестве IDE VB.NET пытается сохранить регистр существующих идентификаторов, когда он довольно перечисляет блок кода. Красивые списки появляются всякий раз, когда вы уходите от текущей логической строки кода. В этом случае вы переходите от второго объявления SS, симпатичный листер замечает, что существует идентификатор с таким именем, и исправляет его, чтобы он соответствовал регистру.

Это поведение, тем не менее, выполняется исключительно как добавленная пользователем ценность. Это не часть основного языка.

person JaredPar    schedule 20.02.2010
comment
Спасибо, Джаред, интересно узнать, что это только IDE. Я до сих пор не понимаю, почему было бы хорошо, если бы несколько имен представляли разные вещи из-за разницы в имени на всякий случай, но я думаю, что это на другой день. - person Todd Main; 20.02.2010
comment
Я не думаю, что Джаред имел в виду только IDE. Я думаю, он сказал, что компилятор нечувствителен к регистру, поэтому он думает, что ss идентичен SS, но также в качестве помощи при чтении IDE исправляет SS на ss по мере ввода. Таким образом, даже если IDE не исправит регистр, компилятор все равно будет рассматривать два идентификатора как идентичные. - person MarkJ; 22.02.2010
comment
Я до сих пор не понимаю, почему было бы хорошо, если бы несколько имен представляли разные вещи, просто разницей в имени ‹- я чувствовал то же самое перед переключением с VBA / VB6 / VB.NET на C #, я Думала, что иметь имена, различающиеся только по падежам, казалась совершенно опасной. Однако на практике он оказывается весьма полезным и, что удивительно, совершенно не подвержен ошибкам. - person Mike Rosenblum; 07.04.2011
comment
@Mike Я совершенно не согласен с этим. Я никогда не видел смешанных имен, которые ничего не значили, кроме как вызывали путаницу. - person JaredPar; 07.04.2011
comment
Действительно? Я имею в виду что-то вроде void SetColor (color Color) {this.color = color}; Я понимаю, что это может выглядеть опасно, но работает плавно, компилятор не позволит вам ошибиться, а IntelliSense выдает правильные элементы после цвета. по сравнению с цветом ... Меня беспокоит то, что использование этого не требуется - это обеспечивается FxCop и / или StyleCop (я забыл, какие именно), но я бы хотел, чтобы была настройка чтобы среда IDE всегда обеспечивала это при доступе к членам класса вместо того, чтобы потенциально допускать случайное затенение области. - person Mike Rosenblum; 08.04.2011
comment
Но теперь давайте посмотрим на эквивалент в VB.NET, а именно: Private Sub SetColor (ByVal color As Color) Me._color = color End Sub В этом случае, однако, 'color' теперь затеняет 'Color', и поэтому это невозможно. для доступа к «Цвету» без полного пути «System.Drawing.Color». Чтобы обойти это и разрешить такие команды, как color = Color.Red, VB.NET разрешил доступ к статическим членам через экземпляр, поэтому теперь можно написать color = color.Red. - person Mike Rosenblum; 08.04.2011
comment
Это оказалось огромной ошибкой, которую команда VB.NET хотела бы исправить (webcache.googleusercontent.com/), но целью было обойти ограничение нечувствительности к регистру. Решение было намного хуже, чем исходная проблема, которая была очень маленькой. - person Mike Rosenblum; 08.04.2011
comment
В целом, имея большой опыт работы как с VB.NET, так и с C #, я бы сказал, что проблема чувствительности к регистру вряд ли имеет значение, но я действительно чувствую, что дополнительная гибкость, позволяющая разрешить регистр различий, перевешивает потенциальные проблемы, которые по причинам, которые сложно объяснить, на практике кажутся малыми. (Я ожидал больших проблем с этим, когда впервые переключился с VB.NET на C #, но на самом деле я их не видел.) - person Mike Rosenblum; 08.04.2011
comment
@Mike Вы описываете сценарий, в котором идентификаторы в разных областях отличаются только регистром. Я не возражаю против этого. Я возражаю против утверждения, что идентификаторы, определенные в одной области действия с именами, различающимися только регистром, только приводит к путанице. - person JaredPar; 08.04.2011
comment
@ Джаред О, определенно, это была бы безумная идея. Абсолютно жадность. Но в целом, учитывая гибкость, которую допускает язык с учетом регистра (включая некоторые действительно плохие его применения, как вы указали), я считаю, что дополнительная гибкость является небольшим плюсом. Обратной стороной является то, что при использовании VB.NET я обнаружил, что для компенсации мне приходится добавлять имена переменных к или my, что немного прискорбно. - person Mike Rosenblum; 08.04.2011
comment
@MikeRosenblum не пытается усложнять здесь задачу (я тоже предпочитаю C #), но, поскольку случай действительно важен в C #, этот параметр функции должен был быть: SetColor (Color color) {...} - person Valentino Vranken; 25.01.2013

VB в основном нечувствителен к регистру, но есть исключения. Например, литералы и понимание XML чувствительны к регистру. Сравнение строк обычно чувствительно к регистру, в отличие от, скажем, T-SQL, но есть переключатель компилятора, чтобы сравнение строк было нечувствительным к регистру. И, конечно же, есть крайние случаи, когда мы имеем дело с наследованием, COM и динамической языковой средой выполнения.

person Jonathan Allen    schedule 20.02.2010
comment
Хорошие моменты о том, где регистр имеет значение, например, XML-литералы и сравнение строк. Но когда мы говорим, что он в основном нечувствителен к регистру, о чем именно мы говорим? Переходя к Outlook VBA, просто в качестве примера, если я наберу Dim mi as mailitem и subject = mi.subject, имена объектов будут автоматически исправлены на MailItem и mi.Subject. Это заботит компилятор (потому что он всегда автоматически исправляет это) или это красивый код или ...? - person Todd Main; 20.02.2010
comment
Компилятору все равно. Вы можете проверить это, отредактировав файл в блокноте и используя компилятор командной строки. - person Jonathan Allen; 20.02.2010

Да, компилятор VB.NET обрабатывает идентификаторы без учета регистра. И да, это может вызвать проблемы, когда он использует сборки, написанные на другом языке, или использует компоненты COM. Первый случай регулируется Спецификацией общего языка. Соответствующее правило:

Чтобы два идентификатора считались разными, они должны различаться не только своим регистром.

Конструктор библиотеки типов позаботился о случае COM довольно грубо, он заставляет совпадать корпус идентификаторов с одинаковыми именами. Даже если у этих идентификаторов разные роли. Другими словами, параметр метода с именем «index» заставит имя метода «Index» быть преобразовано в «index». Как вы могли догадаться, это вызвало довольно много головной боли :)

person Hans Passant    schedule 20.02.2010

VB сохраняет регистр (в среде IDE), но нечувствителен к регистру. В каком-то смысле это похоже на файловую систему Windows. Считается, что файлы Hello.txt и hello.txt имеют одно и то же имя.

IDE предполагает, что объявление переменной является «правильным» случаем для этой переменной, и корректирует каждый экземпляр этой переменной, соответствующий объявлению. Это делается для красоты и единообразия, но не для функциональности.

Я видел несколько случаев, когда регистр не был автоматически изменен в соответствии с объявлением, и оператор работает точно так же. Вы также можете использовать любой текстовый редактор для написания кода, который будет отлично компилироваться в разных случаях.

Примечание:

Большинство ЛЮДЕЙ думают без учета регистра. Когда мы видим слово «собака», это слово приобретает значение в нашем сознании. Значение слова не зависит от регистра (т.е. независимо от того, по буквам оно «СОБАКА», «ДОГ» или «СОБАКА» по-прежнему лает.) КОМПЬЮТЕРЫ воспринимают слова как отдельные мешки битов. Прописные и строчные буквы - это разные битовые шаблоны и, следовательно, разные.

Поскольку большинство программистов - люди, нечувствительность к регистру кажется более адаптированной к тому, как люди думают, а чувствительность к регистру больше связана с тем, что люди приспосабливают свой образ мышления к ограничениям машины.

person Andrew Neely    schedule 29.07.2011
comment
За исключением того, что программисты должны различать объекты и классы и традиционно использовали для этого изменения (не обязательно, просто соглашение). Так что object.method() и Object.Method() мгновенно распознаются как ссылки и методы на объекты и классы (если вы соответствуете этому соглашению о кодировании). Как и в английском, вы различаете имена собственные и начало предложений с заглавной буквы. Поэтому при чтении или программировании я не думаю, что регистр нечувствителен, иначе я бы упустил какой-то смысл. - person Jason S; 24.08.2011
comment
@ Джейсон, все дело в том, к чему ты привык. Новички в программировании на C сначала предъявляют множество жалоб на чувствительность к регистру, а затем, после нескольких курсов, привыкают к ней. Object.method () и Object.Method () - это всего лишь соглашение, и это самый веский пример чувствительности к регистру. Мне пришлось изменить программу, написанную кем-то другим, в которой были две переменные с именами temp и Temp в одной области, и я скажу вам, что было очень трудно держать их прямо в моей голове. И хотя мы можем распознать нарицательные существительные по заглавным буквам, слова «боб» и «Боб» в нашем мозгу означают одно и то же. - person Andrew Neely; 24.08.2011
comment
Почему в этом случае IDE сохраняет регистр? (Извините). Я думаю, что IDE сохраняет регистр, потому что разработчики MS думают, что case имеет некоторую семантику в мозгу, что так и есть. Но на самом деле VB IDE считает form и Form одинаковыми, что в любом случае сбивает меня с толку. В случае (еще раз извините) с temp и Temp вы можете легко использовать инструменты рефакторинга в C #, чтобы переименовать Temp в bobTemp или что-то еще. Тем не менее, я поддерживаю VB, и кто-то уже сделал Dim form As Form. Теперь, когда я переименовываю, он переименовывает и ссылки на классы, и на объекты. Бля! - person Jason S; 25.08.2011
comment
@ Джейсон, в VB я всегда говорю Dim aform как Form, но я отвлекаюсь. VB поддерживает чувствительность к регистру при поиске. Также я бы поискал As Form и заменил его чем-то глупым, затем переименовал форму во что-то разумное, а затем переименовал somethingstupidback в As Form. Мне действительно нравится изменение регистра, потому что это подтверждает, что я не перебирал имя переменной. - person Andrew Neely; 25.08.2011
comment
Да, но это не замена инструмента рефакторинга, который будет различать ссылку на класс и экземпляр, когда имена совпадают (или отличаются только регистром в VB). Инструменты рефакторинга C #, похоже, могут это сделать. Я не называю классы и экземпляры одинаково. В C # я буду использовать регистр, чтобы различать, но в VB я не могу этого сделать, поэтому я использую буквы в начале. Очевидно, моя проблема в том, что я поддерживаю код другого пользователя, который использовал то же имя. Но это обсуждение становится слишком большим для комментариев, поэтому я оставлю его здесь. - person Jason S; 25.08.2011
comment
+1 за примечание - очень хорошо сказано! Уже достаточно языков с учетом регистра! :) - person Yarik; 18.11.2011


Я не уверен, что понимаю тебя? VB нечувствителен к регистру, поэтому ss и SS - это одна и та же переменная, поэтому компилятор правильно жалуется, что вы повторно объявили переменную.

Я думаю, что переменные не чувствительны к регистру, но имена функций чувствительны.

person Michael Stum    schedule 20.02.2010
comment
но если я использую ss, а затем набираю SS, он автоматически корректируется до ss, что наводит меня на мысль, что компилятор действительно заботится о регистре. - person Todd Main; 20.02.2010
comment
@oTAKU: Дело в том, что IDE меняет регистр, а не компилятор. - person John Saunders; 20.02.2010
comment
VB все еще не особо заботится о случае. IDE пытается очистить код, чтобы переменные оставались неизменными во всем. - person guitarthrower; 22.02.2010

Да, VB нечувствителен к регистру. Иногда это заставляет тех, кто к этому не привык, зацикливаться.

person Xorlev    schedule 20.02.2010

Не нужно изо всех сил пытаться в VB.NET создать код с разными прописными и строчными буквами "написания" идентификатора. Изменение регистра идентификатора в файле, в котором он объявлен, без использования функции «Переименовать» не приведет к обновлению имени в других файлах, хотя редактирование любой строки, содержащей имя, приведет к его соответствию настоящему определению.

Таким образом, можно определить, что VB.NET в основном нечувствителен к регистру, но делает регистр идентификаторов доступным для среды CLR, которая может использовать эту информацию с учетом регистра.

person supercat    schedule 14.07.2010

Я могу только предложить это, что, как я помню из моих учебников по программированию еще в начале 80-х, состоит в том, что чувствительные к регистру языки были (в то время) строго предназначены для уменьшения ошибок времени компиляции. Другими словами, «строгость» была предназначена для развития дисциплины кодирования с большей точностью. Как оказалось, добавление правильной маркировки переменных, классов, методов, функций и всего остального, что вы хотите добавить туда, также претерпело изменения.

Я помню, что почти все эти книги включали рекомендуемый образец использования заглавных букв, нижнего регистра и т.д. CASE решения, или для тех, кто достиг более высокого уровня квалификации. Я думаю, что каждый сталкивается с этой кривой обучения.

Учитывая развитие этих языков и IDE, возникает лучший вопрос: какой язык улучшает мое время разработки? Конечно, если вы не знакомы с каждым из различных языков, ваши возможности ограничены.

person htm11h    schedule 17.05.2013

Постараюсь ответить на ваш второй вопрос.

«Достаточно ли это убедительно для меня, чтобы подумать о переходе на C #, если ситуация с VB.NET каким-то образом ограничивает то, что я могу делать с кодом?»

Создайте WCF WebService с помощью C #. Создайте DataContract (1 класс). Один со свойством "строковый адрес электронной почты". Другой с "строковым адресом электронной почты" в качестве другого свойства. Ваш выбор понимать как личный адрес электронной почты или служебный адрес электронной почты. Или это может быть два разных DataContracts.

Для C # это нормально. Веб-сервис создан нормально. Программа на C # может легко создать WSDL, и все в порядке.

Теперь попробуйте создать WSDL с VB (любой версии). Он скажет, что «электронная почта» уже объявлена, и генерация WSDL не удалась.

Как и все, я предполагал, что это недостаток языка VB. Но!!!

Используйте FxCOP и проанализируйте исходный код C #. FxCOP говорит, что использование электронной почты / электронной почты является проблемой. Рекомендует использовать разные имена, поддерживающие нечувствительность к регистру. Также обратите внимание, что на сегодняшний день .NET framework имеет 106 языков программирования, и есть много языков с включенной чувствительностью к регистру. Мы все движемся в сторону облака и хотим, чтобы наши услуги были доступны для всех платформ / языков программирования.

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

http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Visual_Basic_.NET "http://www.vbrad.com/article.aspx?id=65" rel = "nofollow"> http://www.vbrad.com/article.aspx?id=65

person Venkat    schedule 27.09.2013
comment
Облако использует URI, чувствительные к регистру (что особенно важно для прокси и кеш-серверов). - person binki; 26.12.2017

Скрытие символов (например, поле local hides) также нечувствительно к регистру.

Вот пример:

Public Class C
    Public Name As String

    Public Function M(name As String) As Boolean
        Return String.Equals(name, Name) ' case differs
    End Function
End Class

Вывод компилятора VB.NET декомпилирован (и, следовательно, эквивалентен) следующему C #:

public class C
{
    public string Name;

    public bool M(string name)
    {
        return string.Equals(name, name); // both lowercase
    }
}

string.Equals передается поле дважды. Местное скрыто, независимо от случая. Язык нечувствителен к регистру.

Чтобы явно сослаться на член, например на это поле, необходимо разыменовать член через Me:

Return String.Equals(name, Me.Name) ' differentiate field from local
person Drew Noakes    schedule 10.09.2018

Я не видел, чтобы кто-нибудь прокомментировал ваш явный второй вопрос в конце: «2: достаточно ли это убедительно для меня, чтобы подумать о переходе на C #, если случай VB.NET каким-то образом ограничивает то, что я могу делать с кодом?»

Я предпочитаю более опционный подход, когда C # позволяет программисту выбирать, следует ли ограничивать возможности программиста. Я очень предпочитаю C #, но только из-за чувствительности к регистру я бы даже не подумал, что это близко к изучению языка только потому, что он чувствителен к регистру. важны все функции, и когда я смотрю на преимущества как C #, так и VB.NET, я очень предпочитаю C #. но я дам вам действительно сбалансированную перспективу, предвзято да, потому что у меня есть предпочтения, но я также буду честен в отношении недостатков C #.

Во-первых, у обоих языков есть свои преимущества и недостатки. различия, которые вы можете сделать на одном языке, чего нельзя сделать на другом, сокращаются, поскольку, к счастью, Microsoft улучшает оба языка, и они, похоже, не проявляют несправедливого пристрастия к любому языку.

когда впервые появился C #, у VB не было комментариев XML, которые можно было бы помещать перед методами, которые мне нравились в C #. я ненавидел это в VB.NET. но за прошедшие годы я заметил, что многие функции, которых нет на одном языке, добавляются к другому. (одна и та же команда разработчиков MS разрабатывает и C #, и VB, поэтому логично, что функции должны стать очень похожими.)

но вы спросили, что есть в C #, а в VB нет. вот некоторые, о которых я могу сразу подумать:

1: C # более лаконичен и требует меньше ввода ... МНОГИМИ способами! я даже видел, как глупо говорят, когда делается противоположное утверждение, что VB экономит печатание. но, пожалуйста, послушайте людей, которые говорят вам, что они используют оба языка, и ни один из них не используется редко. Я использую C # и VB, C # дома, потому что мне это нравится (и когда я работаю с C # на работе), и мои недавние запросы на работу, в которых я использую VB, а не C #. так что я все чаще использую VB (уже около 10 месяцев), но, по моим личным показаниям, я предпочитаю C #, а с точки зрения фактического набора текста VB значительно больше печатает. один пример, который я прочитал, где кто-то на самом деле пытался сказать, что VB был более кратким, давал пример 'with ...' с длинной переменной в with, поэтому в VB вы могли просто использовать '.property'. глупо утверждать, что VB нужно меньше печатать. есть несколько вещей (и не только в этом примере), где VB короче, но гораздо больше случаев, когда C # более краток на практике.

но самая большая причина, по которой я считаю C # более лаконичным, - это подробные инструкции VB «IF / THEN». если утверждения являются общими. в C # нет слова «тогда» для ввода! :) также все операторы 'end ...' требуют ввода, который в C # обычно представляет собой всего лишь одну закрывающую скобку '}'. Я читал, что некоторые люди утверждают, что эта более подробная информация в VB.NET является преимуществом для VB, поскольку несколько операторов / символов закрывающего блока могут быть вложены и заканчиваться сразу рядом друг с другом, но я совершенно не согласен. человек почти всегда может написать программу на C # или VB лучше, чем другой программист, потому что следующая версия кода может быть спроектирована лучше. это относится к «запутанным многочисленным закрывающим фигурным скобкам в C #» плюс, если все вложенные блоки имеют тот же тип, что и несколько вложенных IF, тогда VB страдает той же проблемой, что и в C #. в VB это не преимущество. именно эта ситуация является причиной того, что я люблю комментировать, что соответствует моему закрывающему символу или закрывающему оператору на обоих языках. да, это более многословно, но на любом языке у вас есть возможность пояснить, что важно в конкретных ситуационных делах, основанных на суждениях. Я считаю, что ясность кода очень важна.

2: VB не имеет многострочных комментариев. когда я работал с VB, я не возражал. затем я перешел на несколько языков в стиле C. Теперь я снова использую VB.NET на работе и скучаю по ним. это просто то, что тебе удобно, а потом приходится терять. :(

3: «andalso» и «orelse» в VB довольно неприятно набирать все это, когда в C # это просто «&&» и «||». опять же, меньше печатать. это не редкость в моем коде как на VB, так и на C #. во всяком случае, для функциональности 'OR' против 'OrElse' обычно не имеет значения, за исключением того, что 'OrElse' быстрее для компьютера, поэтому, если программист просто использует 'Or' и 'And' в VB, он создает менее оптимальный код для тот, кому нравится ясность кода. «Или» гораздо легче пролистать, чем «OrElse».

4: больше гибкости в размещении кода на C #. когда строка длинная, и вы хотите перенести ее на следующую строку, я ненавижу "управляющую" корректировку моего кода в VB.NET. C # делает это немного, но я считаю, что это более полезно в C #, тогда как в VB это гораздо больше контроля. но это скорее VB.NET IDE и C # IDE, чем сам язык. но я не знаю, нужны ли вам оба или чисто языковые функции без различий в среде IDE.

5: один, который мне очень не хватает, - это просто создание нового блока кода на C #, у меня может много чего происходить в методе, и я хочу объявить переменную в очень маленьком блоке кода, но не объявить эту переменную вне этого блока в весь метод. в C # мы можем просто создать новый блок с помощью '{' и закончить его с помощью '}'. VB не имеет такой функции, но наиболее близким совпадением является безусловный блок «If True Then» и «End If». (обратите внимание на 2-символьный C # против 18-символьного эквивалента VB.NET снова ... больше ввода в VB.)

6: операторы самоприращения и декремента: ++ и - как в myVariable++ или ++myVariable или в эквивалентных версиях декремента. это очень удобно ... иногда. вот пример реального кода, когда я сильно скучал по C #:

// C#:
while (txt.Length > x)
{
    thisChar = txt[x];
    if (charsAllowedWithoutLimit.Contains(thisChar)) { ++x; }
    else if (allowLettersWithoutLimit && char.IsLetter(thisChar)) { ++x; }
    else if ((x2 = charsAllowedWithLimit.IndexOf(thisChar)) >= 0)
    {
        ++x; if (++usedCountA[x2] > charAllowedLimit[x2]) { break; }
    }
    else { break; }
}

' VB.NET:
While (txt.Length > x)
    thisChar = txt(x)
    If (charsAllowedWithoutLimit.Contains(thisChar)) Then
        x += 1
    ElseIf (allowLettersWithoutLimit AndAlso Char.IsLetter(thisChar)) Then
        x += 1
    Else
        x2 = charsAllowedWithLimit.IndexOf(thisChar)
        If (x2 >= 0) Then
            x += 1
            usedCountA(x2) += 1S
            If usedCountA(x2) > charAllowedLimit(x2) Then Exit While
        Else
            Exit While
        End If
    End If
End While

И просто чтобы дать ОЧЕНЬ хороший пример правил C #, это еще один код, который я написал недавно:

// C#
public static bool IsNotWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }

public static bool IsWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }

' And the VB equivalent is a mess! Here goes:
<Extension()>
Public Function IsNotWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsNotWithin(v%, value1%, value2%) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsNotWithin(v&, value1&, value2&) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsNotWithin(v@, value1@, value2@) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsWithin(v%, value1%, value2%) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsWithin(v&, value1&, value2&) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsWithin(v@, value1@, value2@) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

Возможно, это достаточное доказательство того, что C # более лаконичен. Но не всем программистам нравится лаконичность. Некоторые предпочитают читать «если a‹ b, то ... », потому что это более естественно для их человеческого языка. И это нормально. Предпочтения в порядке. Для меня усилие руки - это значение фактора i, и я думаю, что любой может привыкнуть думать любыми символами, которые ему нравятся, поскольку «if» и «then» - это символы алфавита, а C # - «оператор if (условие);» синтаксис - это тоже символы. один просто ближе к синтаксису непрограммиста, чем другой. Я предпочитаю лаконичный.

Я также думаю, что необходимость использовать 'c' после символьных литералов в VB, чтобы сделать его символьным литералом, а не строкой, раздражает. Мне гораздо больше нравится лаконичность C #. когда для метода требуется символьный литерал, вам нужно предоставить символ, а не строку с длиной в один символ, поэтому иногда вы вынуждены использовать ":"c в VB, а в C # это ':'. Я думаю, что это придирки.

Честно говоря, я скажу, что у VB есть преимущества, такие как отсутствие пустых скобок после вызовов методов, например Dim nameUpper$ = name.ToUpperInvariant, где C # требует пустых скобок: string nameUpper = name.ToUpperInvariant(). или вдвое больше, чем обрезка: Dim nameUpper$ = name.Trim.ToUpperInvariant vs string nameUpper = name.Trim().ToUpperInvariant(). Мне нравится краткое использование VB того, как я просто использовал $ выше, чтобы затемнить его «As String», где C # не имеет этих ярлыков. VB имеет эти ярлыки для типов String, Integer, Long, Decimal, Single и Double, но недостатком является то, что они менее понятны, поэтому я использую их с осторожностью. но, тем не менее, я предпочитаю лаконичный код.

Что ж, это всего лишь несколько слов от этого опытного программиста, и, как я считаю, это мое «свидетельство» программирования C # и VB. на мой взгляд, оба - хорошие языки. но да, я по-прежнему предпочитаю C #.

p.s. Поскольку я планирую программировать большую часть своей жизни, я даже заново научился печатать, используя самую эффективную клавиатуру: клавиатуру Дворжака, которая требует примерно 1/3 усилий для набора английского языка, чем на клавиатуре Qwerty. поищи это. возможно, вы тоже захотите переключиться. ;) мне стало легче печатать на 67%! :) Я призываю всех мыслить нестандартно и оценивать эффективность своей работы. Упрощенная раскладка клавиатуры Дворжака и C # сделали это за меня. :)

P.S.S. Я бы сравнил Dvorak и C # с метрикой, в отличие от раскладки клавиатуры Qwerty, и VB с эмпирическими измерениями. Дворжак, метрика и C # просто «чистые». НО VB не сильно отстает. Но он страдает от необходимости быть обратно совместимым со старым кодом VB6 и кодом до .NET, например, «Or» против «OrElse» и «IIF ()».

Я заканчиваю с осторожностью. Пожалуйста, будьте более осмотрительны, чем прислушивайтесь к людям, которые на самом деле не понимают, о чем они говорят. Половина всех минусов как VB, так и C # больше не, и люди все еще пишут о них, не зная, какие недостатки действительно все еще существуют в языке. Лучший пример, который я могу придумать, - это комментарии XML для методов, использующих тройной апостроф в VB или символы комментария с тройной косой чертой в C #. Но, пожалуйста, определите для себя, говорит ли человек по незнанию или по опыту. Личное свидетельство означает, что они знают на собственном опыте. А после того, как у кого-то будет большой опыт в этом, тогда придайте уши. У меня более 10 лет опыта как в C #, так и в VB. И все сводится к следующему: оба (очень) хорошие языки. И большинство различий вы можете увидеть сразу через 5 минут после чтения кода. Но да, у других функций могут потребоваться годы, чтобы найти недостаток. И один недостаток, о котором я знаю (в C #), я даже не могу представить себе реальную жизненную ситуацию, в которой это было бы полезно. Так что, возможно, это все-таки не помеха.

Удачного кодирования!

person Shawn Kovac    schedule 24.01.2014
comment
Я ценю все детали, но в вашем примере не используется чувствительность / нечувствительность к регистру (насколько я могу судить), чтобы показать, почему C # в чем-то лучше. - person Todd Main; 16.05.2017
comment
Я попытался ответить на второй вопрос прямым примером. - person Venkat; 06.06.2017
comment
@ToddMain, правильно. И мой пример не использует чувствительность к регистру, чтобы показать почему C # лучше, потому что вопрос не спрашивает почему чувствительность к регистру делает его лучше. Кроме того, я считаю, что эта функция говорит сама за себя. И я считаю, что основная логика заключается в том, что большинство людей может сделать это самостоятельно. Но если кто-то спросит, я рад помочь им понять логику. Но это, мой друг, на мой взгляд, другой вопрос. ;) - person Shawn Kovac; 13.06.2017
comment
Собственно, это был один из двух вопросов, заданных в исходном посте. Это не само собой разумеющееся, поэтому я спросил. Но не беспокойтесь о том, чтобы не ответить на этот вопрос. - person Todd Main; 14.06.2017
comment
@ToddMain, я понимаю вашу точку зрения. действительно очень справедливый момент. :) Спасибо, что открыли мне на это глаза. :) - person Shawn Kovac; 14.06.2017

VB.NET нечувствителен к регистру.

Примеры:

1.

Dim a As Integer
Dim A as Integer

2.

Sub b()
    'Some statement(s) here
End Sub
Sub B()
    'Some statement(s) here
End Sub

3.

Function c() As Integer
    'Some statement(s) here
End Function
Function C() As Integer
    'Some statement(s) here
End Function

Весь этот код вызовет ОШИБКУ ВРЕМЕНИ СОБЫТИЯ.

Для 1-го примера будет показана ошибка: «Локальная переменная 'A' уже объявлена ​​в текущем блоке.».

В то время как для 2-го и 3-го примеров будет отображаться сообщение об ошибке «Public Sub b ()» имеет несколько определений с идентичными подписями ». и «'Public Function c () As Integer' имеет несколько определений с идентичными подписями.» соответственно.

Из этих ошибок обратите внимание, что ошибки возникают в разных позициях для переменных и процедур / функций. Для переменных ошибка выдается при втором объявлении, а для процедур / функций - при первом объявлении / определении идентичного кода.

Как сказал пользователь в комментарии где-то выше, код VB.NET постоянно проверяется и / или корректируется в фоновом режиме; вы можете увидеть эту ошибку в окне «Список ошибок» в VS IDE. И поскольку это ОШИБКА и НЕ ПРЕДУПРЕЖДЕНИЕ, код не будет компилироваться, пока ошибка не будет устранена.

person Nikunj Bhatt    schedule 05.10.2012