Есть ли проблемы с использованием Dim foo As Foo в VB.NET?

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

Foo foo = new Foo(); // C#

Dim foo As New Foo() ' VB.NET

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

Однако, к моему удивлению, это также отлично работало почти в 100% случаев * в VB.NET. Единственная проблема заключалась в том, что имя переменной тогда казалось множественным идентификатором. А именно, его можно использовать для вызова как методов экземпляра, так и общих (статических) методов класса Foo. Однако на самом деле это не вызывало никаких проблем, это просто означало, что Intellisense предоставит список, содержащий как статические методы, так и методы экземпляра, после того, как вы нажмете «.». после имени переменной.

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

Вот немного более длинный пример:

Dim collection as Collection = New Collection()
For Each bar As Bar in Bar.All()
    collection.SomeInstanceMethod(bar)
Next
collection.SomeSharedMethod()

* Единственная проблема, которую я обнаружил, заключалась в том, что иногда инструмент рефакторинга «Переименовать» путался, т. Е. При переименовании класса он переименовывал переменные с тем же именем, что и класс, в их строках объявления (Dim foo As...), но не другие ссылки на эту переменную вызывают проблемы с компилятором. Хотя это всегда было легко исправить.

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

Кто-нибудь еще пытался разрешить это в командной среде? Существуют ли какие-либо другие потенциальные проблемы с этим соглашением об именах в VB.NET?


person Sam Salisbury    schedule 28.08.2009    source источник
comment
Это одна из причин, по которой мне не нравится VB.NET: в C# Foo и foo явно разные идентификаторы, в VB это сбивает с толку...   -  person Thomas Levesque    schedule 28.08.2009
comment
Это одна из причин, по которой я не люблю C#. Являются ли Томас Левеск и ТОМАС ЛЕВЕСК и Томас Левеск разными людьми?   -  person Ryan Lundy    schedule 28.08.2009
comment
Нет, но, к счастью, код C# не предназначен для размещения непосредственно в телефонной книге.   -  person recursive    schedule 28.08.2009
comment
@Kyralessa: хорошая мысль;). Я думаю, что это просто вопрос личных предпочтений в любом случае...   -  person Thomas Levesque    schedule 28.08.2009
comment
Что ж, спасибо всем за вклад в это, я получил немного больше информации о плюсах и минусах (в основном минусах) использования этого соглашения об именах в VB.NET... Я разместил ссылки на основные статьи Microsoft. в моем сводном ответе ниже: ="есть ли проблемы с использованием dim foo as foo в vb net">stackoverflow.com/questions/1347569/ Мне было бы интересно услышать, думает ли кто-нибудь, что знает единственный верный способ написать хорошую переменную VB.NET имена. Всем привет   -  person Sam Salisbury    schedule 28.08.2009


Ответы (9)


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

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

Если вы удалите объявление переменной, компилятор будет думать, что другие ссылки на эту переменную теперь относятся к типу, но на самом деле это не проблема, потому что они будут помечены как ошибки.

person Meta-Knight    schedule 28.08.2009
comment
Yay я не единственный, кто не думает, что это так плохо! :) Хорошая мысль об удалении объявления переменной, вы правы, нет причин для путаницы, потому что у вас не может быть статического (общего) члена с той же сигнатурой, что и член экземпляра, поэтому компилятор не может запутаться в этом вопросе. Intellisense даже не запутается... Думаю, это должно о чем-то говорить. - person Sam Salisbury; 28.08.2009

Хотя VB нечувствителен к регистру, компилятор достаточно умен, чтобы не путаться между экземпляром объекта и классом.

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

person Moayad Mardini    schedule 28.08.2009
comment
Одна из таких опасностей заключается в том, что если объявление foo исчезнет (будет закомментировано или даже просто вырезано для вставки), то компилятор изменит разрешение, чтобы указать обратно на тип, по сути беря предполагаемый Dim foo as new Foo() и преобразуя его в Dim Foo as New Foo(). Больно содержать в чистоте! - person STW; 28.08.2009
comment
Да, у меня есть ощущение, что это может запутать некоторых людей, но поскольку компилятор обрабатывает это так надежно и детерминировано, неужели это действительно так плохо? Я бы хотел, чтобы компилятор, вероятно, по крайней мере предупредил бы, если не выдал бы настоящую ошибку об этом, если бы у него была какая-либо возможность вызвать незапланированное поведение и/или преобразование такого кода VB.NET в IL было неопределенным. - person Sam Salisbury; 28.08.2009
comment
Сэм, как говорят многие преподаватели информатики, только потому, что вы можете это сделать, не означает, что вы должны это делать. Хотя компилятор не жалуется, это ПЛОХАЯ практика, которой следует избегать. - person Moayad Mardini; 28.08.2009
comment
Просто неправильно говорить, что это очень опасно. Мояд, ты отвечаешь Сэму, говоря, что это плохо, потому что это плохая практика. Я бы не назвал это спором ;-) - person Meta-Knight; 28.08.2009
comment
Хм, я думаю, это немного спорный вопрос... Хотя я согласен с Мета-Рыцарем, вы не можете просто утверждать, что это ЯВЛЯЕТСЯ плохой практикой. (Я не говорю, что это неплохая практика, но, может быть, она не НАСТОЛЬКО плоха, я прекрасно понимал ее на протяжении всей начальной разработки, и ее все еще легко отлаживать.) LOL, да ладно, мне нужно найти лучший способ, чем использование традиционного VB. ‹a href=en.wikipedia.org/wiki/Hungarian_notation›Венгерский обозначение‹/ a›, и мне не хочется придумывать описательное эссе для каждой переменной, которую я хочу объявить. Официальная документация MS, похоже, мало что говорит об этом. - person Sam Salisbury; 28.08.2009
comment
Давайте попробуем еще раз... Это означало "венгерская нотация"! Я немного новичок в этом, лучше прочитайте документы. В любом случае, теперь есть ссылки на официальную документацию MS в качестве комментариев к исходному вопросу, если кто-нибудь знает единственный верный способ красиво называть вещи в VB.NET, пожалуйста, дайте мне знать! Спасибо всем - person Sam Salisbury; 28.08.2009
comment
Мета-Рыцарь, я согласен, это был не очень хороший ответ :) Сэм, вы можете сослаться на: Cwalina, Krzysztof и Brad Abrams. Рекомендации по разработке платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET. Бостон, Массачусетс: Addison-Wesley Professional, 2005. - person Moayad Mardini; 29.08.2009

Мне приходится переключаться между VB и C#, и мы считаем это плохой практикой. Нам также не нравится, когда имена переменных в C# отличаются от их типа только регистром. Вместо этого мы используем префикс _ или даем ему более осмысленное имя.

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

Не на 100 % правильно говорить, что VB.Net нечувствителен к регистру, если вы также не указываете, что он с учетом регистра. Когда вы объявляете идентификатор variable, IDE заметит, какой регистр вы использовали, и автоматически исправит другие варианты использования, чтобы они соответствовали этому регистру. Вы можете использовать эту функцию, чтобы помочь обнаружить опечатки или места, где IDE может запутаться в переменной или типе. На самом деле я предпочитаю это реальным схемам с учетом регистра.

VB.Net импортирует пространства имен по-разному. Если вы хотите использовать класс File, вы можете просто сказать IO.File без необходимости импортировать System.IO вверху. Эта функция особенно удобна при изучении нового API с несколькими вложенными слоями пространства имен, потому что вы можете импортировать раздел верхнего уровня API, ввести имя следующего пространства имен, и вам будет предложен список классов в этом пространстве имен. . Здесь это трудно объяснить, но если вы поищите и начнете использовать его, то, вернувшись к C#, вам его будет очень не хватать. Главное то, что, по крайней мере для меня, это действительно ломает мой поток, чтобы перейти к началу файла, чтобы добавить еще одну директиву using для пространства имен, которое я могу использовать только один или два раза. В VB это прерывание встречается гораздо реже.

VB.Net выполняет фоновую компиляцию. В тот момент, когда ваш курсор покидает строку, вы узнаете, скомпилируется ли эта строка. Это несколько компенсирует отсутствие выделения имен классов, потому что отчасти это полезно в C#, чтобы вы знали, что набрали его правильно. VB.Net дает вам еще больше уверенности в этом отношении.

person Joel Coehoorn    schedule 28.08.2009
comment
Интересные заметки, спасибо. Я заметил (и был потрясен) вложенность пространств имен при использовании VB.NET, хотя я понимаю ваше замечание о том, что это хорошо для начинающих или тех, кто никогда не удосужится изучить более лаконичный язык, такой как C #. Вы можете просто ввести имя класса и нажать Ctrl+Space, чтобы, кстати, автоматически вставить объявление using Namespace в C#, если у вас есть ссылки на место. - person Sam Salisbury; 28.08.2009

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

person Brian Gideon    schedule 28.08.2009
comment
Хм, со мной такого еще не случалось, думаю, это может быть самой убедительной причиной не использовать эти имена! Какую версию Visual Studio вы используете? Я только когда-либо использовал 2008 - person Sam Salisbury; 28.08.2009
comment
VS 2008. Это происходит не постоянно. - person Brian Gideon; 30.08.2009

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

Лучшей практикой является попытка назвать переменную в том контексте, в котором она используется, а не просто имя типа. Это приводит к самодокументированному коду и требует меньшего количества комментариев (комментариями часто злоупотребляют как предлогом для написания плотного кода).

person STW    schedule 28.08.2009
comment
Да, я определенно согласен, когда речь идет о более длинных методах, но для действительно небольших служебных методов часто ничего не известно о контексте, в котором вызывается функция, что могло бы обеспечить более описательное имя. - person Sam Salisbury; 28.08.2009
comment
Я бы проголосовал за вас, если бы у меня было достаточно репутации, хотя мне нужно 15 :( - person Sam Salisbury; 28.08.2009

Это безопасно только в том случае, если компилятор всегда может сказать, означает ли Foo класс или переменную, и в конечном итоге вы столкнетесь с ситуацией, когда это невозможно. Эрик Липперт обсуждает, что может пойти не так на его блог.

person stevemegson    schedule 28.08.2009

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

Единственный минус — когда какой-то инструмент неправильно интерпретирует контекст. Например, Visual Studio 2010 beta 1 иногда использует выделение класса для переменных, названных так же, как и класс. Это немного раздражает.

Контекстная чувствительность намного ближе к тому, как я думаю, чем чувствительность к регистру.

person Craig Gidney    schedule 28.08.2009
comment
Круто, значит, VS 2010 будет подсвечивать синтаксис для VB лучше, чем VS 2008? Я думаю, что с этим дополнением не может быть абсолютно никаких причин не использовать это соглашение... Кстати, что вы имеете в виду под своим последним предложением? - person Sam Salisbury; 29.08.2009
comment
Да, он выделяет классы голубым цветом. Последнее предложение означает, что мне больше нравятся контекстно-зависимые языки, чем регистрозависимые. - person Craig Gidney; 29.08.2009

Что ж, это не окончательный ответ, и я не думаю, что есть окончательный, но общее мнение, похоже, таково, что использовать это соглашение об именах не очень хорошая идея! Однако должен быть один верный способ написать красивые имена переменных VB.NET, и мне не нравятся никакие альтернативы...

Вот ссылки на официальные руководства Microsoft для всех, кто заинтересован, хотя они, кажется, не охватывают этот конкретный вопрос (пожалуйста, поправьте меня, если я пропустил это).

Соглашения об именах Visual Basic: http://msdn.microsoft.com/en-us/library/0b283bse.aspx

Объявленные имена элементов: http://msdn.microsoft.com/en-us/library/81ed9a62.aspx

Здоровья всем!

person Sam Salisbury    schedule 28.08.2009

VB.NET не чувствителен к регистру! Это равно:

Foo Foo = new Foo(); // C#

В качестве стандарта в нашей командной среде мы будем использовать:

Dim oFoo as New Foo 'VB.NET
person stevehipwell    schedule 28.08.2009
comment
Да, но вы бы не написали это ;) - person stevehipwell; 28.08.2009
comment
Не для локальных переменных, но свойства обычно имеют то же имя, что и их тип. См. это сообщение Эрика Липперта: blogs.msdn.com /ericlippert/archive/2009/07/06/color-color.aspx - person Thomas Levesque; 28.08.2009
comment
@Thomas: правда, но магазины VB.NET будут стараться избегать этого для компонентов, которые они контролируют именно по этой причине. Это не слишком большая проблема при использовании сторонних сборок, но в основном проблема при написании сборок с этими конфликтами имен. - person STW; 28.08.2009