Действительно ли префиксы переменных («венгерская нотация») действительно необходимы?

Поскольку C# строго типизирован, действительно ли нам нужно больше префикса для переменных?

например

iUserAge
iCounter
strUsername

Раньше я использовал приставку, но в будущем я не вижу никакой пользы.

Дубликат: stackoverflow.com/questions/111933/…

Jason Baker 27.05.2009 00:55

Интересно прочитать о происхождении венгерской системы обозначений и о том, почему они изначально имели смысл: joelonsoftware.com/articles/Wrong.html

Timwi 24.08.2010 02:44

Связанный: stackoverflow.com/questions/202107/…

Lance Roberts 14.03.2013 20:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
39
3
7 793
29

Ответы 29

Неа. Нам Когда-либо нужно было?

Эндрю, код joels полон префиксов как для переменных, так и для столбцов таблицы.

Blankman 21.11.2008 19:13

Правда. Я хотел провести различие между «Петцольдом Венгриком», примеры которого приводил спрашивающий, и реальным.

Andrew Cowenhoven 01.12.2008 19:59

+1 за JoelOnSoftware ... он гений

Bob Fincheimer 17.08.2010 20:48

Нет. Венгерская нотация просто добавляет ненужный шум в код и является избыточным при проверке типа компилятора.

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

Линус хорошо подытоживает: «Кодирование типа функции в имени (так называемая венгерская нотация) - это повреждение мозга - компилятор все равно знает типы и может их проверить, и это только сбивает с толку программиста»

Префиксы - это пережиток времен VB (и старше!), Когда Венгерская нотация был королем. Это уже не так, хотя C# сообщество действительно требует такие вещи, как использование префикса Capital I для интерфейсов (например, ILoadable).

Текущие рекомендации Microsoft - здесь.

Are variable prefixes ( Hungarian ) really necessary anymore?

НЕТ!

Фактически, собственный рекомендации по стилю Microsoft (где зародилась такая практика) теперь рекомендует не использовать его. В частности, см. Раздел о Общие правила именования, который включает следующий текст (не менее жирным шрифтом):

Do not use Hungarian notation.

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

Другими словами, не используйте их больше.

Честно говоря, рекомендации по стилю MS для больших частей произвольны и, следовательно, не являются полезной точкой отсчета.

Konrad Rudolph 21.11.2008 23:38

@Konrad, потому что что-то произвольное, не означает, что они бесполезны. Иногда просто наличие стандарта а само по себе полезно. Наличие чего-то последовательного - это мощно. Венгерский, возможно, непоследователен. Флажок? cb? cbox? ckb? Вот почему я борюсь с этим.

Kenny Mann 13.03.2009 16:55

С каких это пор последнее слово за авторами рекомендаций в MS? Конечно, стандарты хороши, но не тогда, когда они конкретизированы. Как раз сегодня я писал iaWhichDose, потому что мне нужно было что-то, в котором четко говорилось бы, что это был целочисленный массив индексов "какая доза", и iCat, в котором ясно говорилось, что это индекс категории. Название говорит мне, что оно означает, не вдаваясь в подробности. Что, черт возьми, можно сделать, запретив это?

Mike Dunlavey 26.02.2010 02:23

@Mike - Откуда вы взяли «конкретное / запрещенное» от «[больше не] действительно необходимо / не рекомендую»?

Joel Coehoorn 26.02.2010 03:04

Руководящие принципы стиля MS "рекомендуют против"? Говорят «Не использовать венгерскую нотацию»? Может быть, это только я, но разве это немного догматично?

Mike Dunlavey 26.02.2010 04:19

@MikeDunlavey В таких случаях я бы предложил WhichDoseIndexes и CategoryIndex. Аббревиатуры тоже не читаются. Обычные английские длинные имена имхо лучше.

ErikE 09.06.2014 21:30

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

Однако я НАСТОЯЩИМ, что вы делаете префиксные элементы управления с их типом, например txtName.

Приставки на элементах управления сводят меня с ума.

g . 21.11.2008 21:22

Единственный префикс, который я бы рассмотрел для C#, - это _ для переменных-членов, таких как

public class Test
{
    private int _id;
}

Это часть стандартного стиля?

James McMahon 21.11.2008 19:11

Да, это так. Стандарт MS для частных переменных-членов (по крайней мере, в C#, не уверен в VB.NET) заключается в добавлении к ним префикса подчеркивания. Это полезно с инструментом рефакторинга в Visual Studio. Вы можете щелкнуть правой кнопкой мыши переменную-член с префиксом подчеркивания, выбрать «Инкапсулировать», и она сгенерирует соответствующее свойство переменной-члена, включая методы получения и установки. Вот так: private int _id; будет генерировать: public int Id {get {return _id; } установить {_id = значение; } } Сладкий!

Cyberherbalist 07.05.2009 00:41

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

Я иду с Microsoft и использую их Стили заглавных букв для всех соглашений об именах. На мой взгляд, весь раздел «Рекомендации по дизайну для разработчиков библиотек классов», частью которого является эта ссылка, является чистым золотом.

Кроме того, мне нравится книга «Рекомендации по разработке каркаса» от Аддисон Уэсли. Он охватывает все эти руководящие принципы с комментариями членов команды Microsoft о том, почему они рекомендуют то, что они предлагают, и как это применяется в организации.

Общий обзор хороших соглашений см. Здесь: http://msdn.microsoft.com/en-us/library/ms229002.aspx

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

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

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

Только если вы читаете код вне IDE. Если он находится в среде IDE, вся информация доступна, просто наведя указатель мыши на переменную.

Joel Coehoorn 21.11.2008 19:11

Это предполагает многое о среде IDE, которую другой читатель кода имеет в наличии и предпочитает использовать. Я не предполагаю, что в моем коде есть IDE, и я очень поддерживаю позицию, которую предлагает здесь Франс-Виллем.

orcmid 22.11.2008 00:27

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

Я полностью за решения совместной команды, но я не могу согласиться с тем, что команда должна использовать устаревшие стандарты для комфорта. Честно говоря, это не способствует развитию навыков, чтобы делать что-то определенным образом, потому что «всегда так делалось». Просто добавляю счетчик к своему счетчику. :-)

Joseph Ferris 21.11.2008 19:13

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

Cory Foy 23.11.2008 05:22

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

В языках, которые имеют подписанные и беззнаковые типы или множество подобных типов (например, short, int, long или Int8, Int16, In32), тогда префиксы полезны, несмотря на то, что кто-то еще имеет или скажет (и они, как вы знаете, Это).

Компилятор, в лучшем случае, выдаст предупреждение, когда вы попытаетесь смешать целые типы с разными знаками в выражениях, и это можно легко пропустить, если, например, вы настроите свою IDE так, чтобы отображались только ошибки (а не предупреждения) в сборке в окончательное резюме (как и в Visual Studio). Смешение знаков в арифметике может серьезно испортить вам день, поэтому избавьте вас или вашего преемника от головной боли и дайте им ключ к разгадке. Помните - вы не единственный, кто когда-либо будет смотреть на код.

Единственные места, которые я считаю подходящими для изменения стандартных и префиксных переменных:

  • имена элементов управления: txtWhatever - и я вижу, что я не единственный. Приятно то, что вы можете придумать такие вещи, как lblName рядом с txtName, и вам не нужно идти в направлении NameLabel / NameTextBox.

  • переменные-члены класса: _whatever. Я пробовал и m_, и вообще без префикса, и в итоге получил простое подчеркивание. m_ сложнее набирать, и отсутствие префикса иногда сбивает с толку (особенно во время обслуживания, я знаю, что все вы знаете свой код наизусть, когда пишете его)

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

Обновлено: Я прочитал рекомендации Microsoft. Однако я считаю, что стили кодирования могут развиваться и / или «изгибаться», где это уместно. Как я уже упоминал выше, я обнаружил, что использование префикса подчеркивания полезно методом проб и ошибок и, безусловно, лучше, чем использовать this.wesome везде в коде.

Поддерживая «развивающуюся» теорию - еще в .NET 1.x, когда Microsoft выпустила руководство по кодированию, они посоветовали использовать Camel-регистр для всего, даже для констант. Теперь я вижу, что они изменились, и советую использовать регистр Паскаля для постоянных или общедоступных полей только для чтения.

Более того, даже библиотека классов .NET Framework в настоящее время заполнена m_, _ и s_ (попробуйте просмотреть реализацию с помощью Reflector). В конце концов, это зависит от разработчика, если в вашем проекте сохраняется согласованность.

Префикс _ действительно хорош для частных членов, если вам нужно много перемещаться между VB и C#, поскольку соглашение хорошо работает в обоих местах.

Joel Coehoorn 21.11.2008 20:07

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

Dan C. 21.11.2008 20:31

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

Ray 21.11.2008 22:32

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

Я также почти уверен, что наткнулся на префикс м_, просматривая стандартные библиотеки .NET с помощью Reflector ...

Кто-то ненавидит префикс локальных переменных-членов, это точно :)

Dan C. 21.11.2008 20:02

+1 от меня ... но я использую соглашение без подчеркивания ... и g для переменных в глобальном пространстве имен. (Это на C++)

activout.se 21.11.2008 20:36

Решение проблемы, которой не существует.

Да, если бы венгерские обозначения использовались в том виде, в каком они были изначально задуманы, а не в том виде, в котором они реализованы Microsoft. Как и в приведенном выше примере, где текстовые поля и соответствующие метки показаны как lblWhatever, txtWhatever. Используйте его, чтобы определить использование переменной, а не ее тип. Он может предоставить информацию о том, что ваш номер - moneyTotal, что говорит мне не только о типе данных.

Но как обычно используется? Нет.

ИМХО, Java была бы намного лучшим языком, если бы венгерская нотация использовалась в том виде, в каком она была изначально задумана. Если поле имеет тип int[], часто очень важно знать, могут ли существовать другие ссылки на тот же массив и может ли когда-либо измениться содержимое этого массива. В системе типов Java ничего не говорится об этих вещах, но включение такой информации в имена может сделать многие виды ошибок более очевидными.

supercat 14.02.2014 04:11

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

  • Если вы поддерживаете код, уже использует его, тогда я бы оставил используй это.

  • Когда рекомендации по стилю вашей компании все еще требовать или даже предлагать это.

  • Когда в вашей документации есть простой алфавитно-цифровой список переменные, это помогает группировать похожие типы.

Точно нет. По общему правилу, я пришел к выводу, что это просто шум. Если вы независимый консультант или у вашей компании нет подробного руководства по стилю, у IDesign есть отличное руководство. Просто посмотрите на правую часть страницы, и вы сможете D / L последней итерации их документа C# Coding Standard.

Стив

Если венгерский означает «префикс с аббревиатурой типа», такой как uCount или pchzName, то я бы сказал, что эта практика плохая и, к счастью, постепенно исчезает из общего использования.

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

i_  // input-only function parameter (most are these)
o_  // output-only function parameter (so a non-const & or * type)
io_ // bidirectional func param
_   // private member var (c#)
m_  // private member var (c++)
s_  // static member var (c++)
g_  // global (rare, typically a singleton accessor macro)

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

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

Есть и забавные дополнительные преимущества, такие как Intellisense. Вы можете ввести i_ ctrl-space и получить все входные параметры функции на выбор. Или g_ ctrl-space, чтобы получить все ваши синглтоны. Это экономия времени.

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

MighMoS 25.07.2009 03:23

Это мое любимое соглашение, хотя я не делаю различий между параметрами ввода / вывода.

M. Dudley 25.01.2011 21:04

Полностью согласен: префиксы типа: нет; префиксы области видимости: да. (хотя я использую другой набор). Дополнительным преимуществом является избежание конфликтов имен; (то есть: поле, параметр и локальный объект могут иметь одно и то же «имя» без излишней креативности: var arg = argument; Argument = argument; VS var agument = pArgument; mArgument = pArgument;).

Dave Cousineau 30.03.2012 03:34

Венгерская нотация больше не нужна для идентификации типов данных, как в примере со строкой, но она по-прежнему может быть полезна для определения характеристик переменных другими способами. Вот хорошая статья, в которой рассказывается о полезных способах использования венгерской нотации: http://www.joelonsoftware.com/articles/Wrong.html

Вот отрывок

"В версии венгерской системы обозначений Симони каждая переменная имела префикс в нижнем регистре, который указывал на то, что эта переменная содержала.

Например, если имя переменной - rwCol, rw - это префикс.

Я специально использую слово «добрый», потому что Симони по ошибке использовал слово «тип» в своей статье, и поколения программистов неправильно поняли, что он имел в виду ».

Он также использует пример идентификации строк с префиксом 's' или 'u', чтобы определить, безопасны ли они для печати или нет, так что такой оператор, как print (uSomeString); может быть легко идентифицирован как неправильный.

Нет, они нам не нужны. Я следил за этим, когда в те дни мы были вынуждены следовать такому стандарту кодирования.

Также с помощью Intellisense, окна определения кода и инструментов рефакторинга, встроенных в VS и другие сторонние плагины, такие как CodeRush express и Refactor Pro, легче работать с кодом без них.

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

Но когда я работаю с рядом элементов управления пользовательским интерфейсом, будь то текстовые поля, раскрывающиеся списки, сетки или что-то еще, мне нравится, чтобы мой intellisense работал на меня. Поэтому для этого я обычно делаю идентификатор элемента управления с префиксом «uxSomeControlName». Таким образом, когда я ищу это текстовое поле, чтобы получить его текстовое значение, все, что мне нужно сделать, это ввести «ux», и отобразятся все идентификаторы пользовательского интерфейса. Нет необходимости искать txt, ddl, grd или что-то еще.

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

Как я уже сказал, это только при работе с интерфейсом.

Я иногда использую своего рода префикс, где pName - это параметр, переданный в мою функцию (обратите внимание, что я не префикс типа), oName является локальным для моего текущего метода, mName является членом класса, в котором я участвую, а cName постоянный или статический член только для чтения.

Лично я считаю, что это помогает.

Любая современная IDE предоставит вам эту информацию

Steve Kuo 02.10.2014 04:16

Что заставляет меня любопытствовать в этом вопросе, так это тот факт, что языки (C, затем C++), в которых был введен префикс (то есть венгерская нотация), также были строго типизированы. Насколько я знаю, это также было сделано с использованием Паскаля в Microsoft. И, похоже, он также использовался с Mesa, языком со строгим контролем типов, с которым венгры, возможно, были знакомы [; <).

В таком случае будет справедливо уклониться от вопроса и рассмотреть (1) какая проблема использовалась для решения с помощью префикса и (2) как эта проблема исчезла?

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

Что еще более иронично, я никогда не видел, чтобы венгерская нотация использовалась там, где я считаю ее наиболее важной: определение того, является ли поле изменяемого ссылочного типа (например, int[]) единственной ссылкой на безопасно изменяемый объект, или, возможно, совместно используемая ссылка на объект, который, даже если он имеет изменяемый тип, никогда не должен изменяться. Различие чрезвычайно важно, и IMHO Java и C# были бы лучшими языками, если бы они поощряли использование венгерской нотации для различения различных «типов» ссылок.

supercat 21.02.2015 00:24

Я использую его только в своей базе данных (PostgreSQL)

t_ for table name
v_ for view name
i_ for index name
trig_ for trigger


sp_ for stored procedure name
p_ for parameter    
v_ for variable
c_ for cursor
r_ for record

Краткий ответ: нет. Но...

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

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

Кроме того, иногда я задаюсь вопросом: "Какого черта этот флажок был назван снова?" И я должен прерваться и снова заглянуть на страницу .ASPX.

Один из способов, которым я пошел на компромисс, - это начать с HN, а затем, как только я получу основной код в выигрышной или веб-форме, мой последний шаг - выполнить глобальное переименование для элементов управления с именем HN. Это действительно хорошо сработало для меня. YMMV, конечно.

Венгерская нотация никогда не предназначалась для обозначения типа данных переменной. Было неправильно понято предлагать использовать «str» или «i» для неявного определения типа. Он должен был показывать только «вид» переменной, а не «тип».

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

Я знаю, что это было связано, но прокрутите статью Джоэла до конца, чтобы узнать больше - http://www.joelonsoftware.com/articles/Wrong.html, где он говорит о том, где венгерский

Я использую его постоянно, но это возможно, потому что я использую VBA с Access и Excel.

Для меня CountAll - это имя. IntCountAll - это имя с той разницей, что оно дополнительно описывает имя (никогда не предназначалось для машин только для людей), например, sintCountAll сообщает мне свои статические pintCountAll private и gintCountAll global, поэтому для этой цели я использую его; это очень полезно.

  • имена элементов управления - это более безопасное время, например, вместо ControlName у меня есть lblControlName, txtControlName, cboControlName, lstControlName и т.д., поэтому, когда я использую VBA, я просто набираю lst, и у меня есть все имена, которые мне нужны, поэтому мне не нужно запоминать точное имя что экономит мне много времени, но опять же, это в основном VBA в Access и Excel.

С уважением Эмиль

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

А как насчет печатного кода? Разве вы не проводите обзоры кода или пошаговые инструкции на бумаге? Разве вы не используете печатный код в учебных целях? Разве вы не используете фрагменты кода для онлайн-справки? Венгерская нотация очень сильно полезна в таких случаях.

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

Другие вопросы по теме