Pull to refresh

Comments 117

Со всем согласен.
По поводу
3.1 Закрытые поля - я за третий вариант. Первый - это С++, а со вторым вообще не встречался никогда.
3.2 насчет скобок с новой строки поддерживаю, касательно if руководствуюсь такими принципами:
- если в выражении одна строка, то пишу без скобок
- если в if одна строка, а в else несколько (или наоборот), то обе конструкции пишу с фигурными скобками, для более легкой читаемости.
- не использую конструкцию вида if(condition) doSomesthing(); Т.е. не использую однострочную конструкцию if.
Ок.
Второй вариант закрытых полей описан в предложении первого источника, приведенного в начале.
Про if: я поступаю точно так же как и ты, но очевидно, что назвать стандартом проще действие через одно условие, чем через три. Вариант который приведен в статье описан во втором источнике. Причин там не описывается, но я думаю, все дело в читаемости и принципе: область видимости всегда в фигурных скобках. В целом с тобой согласен, но, наверное, стоит еще чье-нибудь мнение послушать, чтобы внести изменения.
Как тогда предлагаешь разделять закрытые поля класса, статические переменные и константы?
в нотации 1 это:
private int m_myVar;
private static int s_myVar;
private const int s_myVar = 10;
А еще при необходимости можно добавлять префикс идентифицирующий тип переменной m_iMyVar для Int32 или m_lMyVar для Int64 (long)
Не, так точно не буду разделять.
Если это закрытое поле (а оно в 99% случаев закрыто), то
private int _myVar;
Константы никак не рекомендуется выделять от других полей, чего и я не делаю.
Статические поля.. К статическому полю нельзя обратиться без имени класса в нестатическом методе. А в статическом - к обычным полям класса. Тут наглядно будет разделение, как по мне и так.
Тип данных в виде префикса - тоже никогда не использую и нет рекомендаций по этому поводу, касательно C#.
Не совсем правда, к статическому полю можно обратиться без имени класса в нестатическом методе этого же класса. В остальном согласен.
Да, это я что-то затупил )
Ещё я практикую называть элементы управления в ASP.NET с префиксом, который описывает их тип. Например:

txtSample - TextBox
lblSample - Label
litSample - Literal
cmdSample - Button, LinkButton, ImageButton
lstSample - Все списковые элементы
odsSample - ObjectDataSource
lnkSample - Hyperlink
imgSample - Image


ну и оcтальные по такому же принципу.
Если этим пользуются остальные, то можно тоже включить в соглашение. Таким же принципом пользуюсь для именования контролов в WinForms
Я тоже так делаю. Это своеобразный вариант венгерской нотации, но теперь, мне кажется, что это не совсем правильно. Совсем не очевидно что такое cmdSample, не лучше ли назвать SampleButton, SampleLinkButton, SampleImageButton? И во всем остальном также:

SampleTextbox,
SampleLabel,
SampleLiteral,
SampleList,
SampleObjectDataSource,
SampleHyperlink,
SampleImage

на самом деле, проигрыш в длине переменной небольшой, но наглядности больше. Как думаешь?
Схожие по функционалу контролы я думаю и нет смысла так уж "пристально" разделять. Я думаю врядли на странице будет 3 кнопки Login всех возможных типов.

И для меня нагляднее, когда название строится по схеме [тип контрола][за что отвечает].
такой порядок — тип контрола, потом его «название» — нагляден, но у него есть мальенький недостаток: обычно в IDE есть автозавершение, и есть есть много элементов типа txt, то в любом случае нужно будет каждый раз набирать txt.
Хотя так действительно нагляднее и психологически удобнееimho ;)

Было бы неплохо, если в IDE была бы автоматическая подстановка по любой подстроке, не только по началу. Т.е. ты вводишь несколько букв, а оно тебе сразу список того, где эти буквы встречаются.
Так у меня уже эти txt, lbl набираются на очень сильном автомате, поэтому дискомфорта не испытаываю. И при их наборе думать сильно не надо. Набрал lst и IDE показывает все списки, которые есть на странице. А если начинать с [за что отвечает], то приходится в голове держать все что у тебя есть на странице и для чего ты его туда поместил :)
Я перешел из именования, типа SampleLabel, в основном по этой причине.
да, автомат сильно помогает вообще всегда ;) Так что действительно, надо просто привыкнуть ;)

Вообщем, когда придётся какую отдельную программу начинать писать — попробую ;) Спасибо ;)
Незачто :)
А каким способом сейчас названия даешь?
Сейчас — как предлагает XaocCPS, но только в camel-нотации: OpenButton, LoginTextEdit. Изредка сокращаю суффиксы.

А метки (Label) вообще никак не именую, если они никогда не изменяются. Даже не знаю, плохо ли это или сойдёт ;) До сих пор проблем не было ;)
Ну я тем контролам, к которым заведомо не буду обращаться с CodeBehind тоже не даю ID. Плохо это может быть при локализации, например.
А вообще по именам, нужно наверное просто все способы попробовать и выбрать для себя лучший. Кому-то одно по душе, кому-то другое.
Не, про camel — это я чего-то ляпнул не того ;)
Раньше, к стати, я именовал контролы так как в твоем примере
SampleLabel. Потом как-то перешел на более удобный для себя.
Может быть:
btnSample - Button, LinkButton, ImageButton
ddlSample - Все списковые элементы

Хотя Ваш вариант тоже неплох.
Насчет Button возможно я и неправ.
А ddl - это от DropDownList ведь? Если так, то ко всем спискам его применять вроде и не корректно. Мое сокращение от List.
или такой вариант
btnSample
lbtnSample
ibtnSample
Похоже большинство за сокращение и суффиксы, приведу тогда вариант от Submain. Прошу согласиться с ним или внести корректировки, потом добавлю в текст.
lbl Label
llbl LinkLabel
but Button
txt Textbox
mnu MainMenu
chk CheckBox
rdo RadioButton
grp GroupBox
pic PictureBox
grd Grid
lst ListBox
cbo ComboBox
lstv ListView
tre TreeView
tab TabControl
dtm DateTimePicker
mon MonthCalendar
sbr ScrollBar
tmr Timer
spl Splitter
dud DomainUpDown
nud NumericUpDown
trk TrackBar
pro ProgressBar
rtxt RichTextBox
img ImageList
hlp HelpProvider
tip ToolTip
cmnu ContextMenu
tbr ToolBar
frm Form
bar StatusBar
nico NotifyIcon
ofd OpenFileDialog
sfd SaveFileDialog
fd FontDialog
cd ColorDialog
pd PrintDialog
ppd PrintPreviewDialog
ppc PrintPreviewControl
err ErrorProvider
pdoc PrintDocument
psd PageSetupDialog
crv CrystalReportViewer
pd PrintDialog
fsw FileSystemWatcher
log EventLog
dire DirectoryEntry
dirs DirectorySearcher
msq MessageQueue
pco PerformanceCounter
pro Process
ser ServiceController
rpt ReportDocument
ds DataSet
olea OleDbDataAdapter
olec OleDbConnection
oled OleDbCommand
sqla SqlDbDataAdapter
sqlc SqlDbConnection
sqld SqlDbCommand
dvw DataView
Например, я бы предпочел dv вместо dvw для DataView и btn вместо rbtn.
А я rad вместо rdo.
img в ASP.NET больше бы относилось к Image — это может сбить c толку.
oled и sqld только догадаться могу как образовались, а автору это, скорее всего, просто очевидно.
Молодец, что собрал всю информацию вместе.
Мои комментарии и дополнения :)
1. Приватные поля - начинать имена с подчеркивания и маленькой буквы.
2. Скобки - я за то, чтобы ставить их всегда. А то иногда одну строчку после условия особо умные комментируют и начинается магия :) - if распространяется на следующую.
3. Про именование контролов - всеми руками за вариант dmx. Точно такой же практикой пользуемся.
А насчет наглядности - после двух-трех дней пользования сокращениями, поймете, что все-таки, они лучше. Нежели сто раз в день видеть TextBox, Literal, ObjectDataSource.
4. Про оформление классов - сначала пишутся все приватные и защищенные поля, позже идут свойства, далее - методы - сначала приватные, потом защищенные и наконец общие.
Обычно, если более одного метода, свойства, поля - мы объединяем в регионы.
Пока ничего больше в голову не приходит...
1. Если считать со мной - это уже третий голос. Наверное так и сделаем.
2. Я тоже за то, чтобы всегда ставить скобки.
3. Я тоже пользуюсь, но когда начинаешь встречать в чужом коде btnSample вместо cmdSample и многое другое не настолько очевидное, начинаешь задумываться, а так ли это уж и правильно? Такая нотация интересная когда она навязана свержу, типа венгерской, которую знали все, потому-что win32 api написан на ней. Но свой вариант нотации - это уже палка о двух концах: себе удобнее, другим все равно...
Мы пишем не на Win32 API :)
Button - btn.
ImageButton - тоже btn(потому как наследник Button).
А вот dmx считает, что cmd. И как тут быть? Завтра появится Вася Пупкин, который захочет вообще писать bSample или ibtnSample. Стоит ли браться за стандартизирование такого скользкого момента, как именование элементов управления через префиксы?
Только хотел отписаться, насчет своего cmd :)
Думаю можно просто включить как рекомендацию.
И префикс трехбуквенный я всегда даю.

Сейчас посмотрю что вообще насчет этого гугл говорит.
Может голосование на Хабре провести, типа кто использует те или иные варианты, если вообще использует?
Не обязательно в контексте .net, это вроде внеязыковый момент.
Я думаю, что сmd - от Command или CommandButton... Я таких контролов как-то не встречал. :(
Я гуглить ходил вообще по поводу именования контролов, а не cmd vs btn :)

Пришел к выводу, что пусть это останется личным делом каждого. Куча статей, и куча разных мнений. Кстати, ко всем вышеобговоренным ещё одно нашел:
Именовать все контролы с префикса ux (User eXperience). Это позволяет в IntelliSense группировать все, что относится к интерфейсу. Говорят удобно :)

PS. cmd, да, от Command. Тут больше происходит от действия, чем от названия самого элемента.
Что думаешь по поводу варианта от Submain?
Как уже писал - это субъективно.
Мне там некоторые вещи ненаглядны, например.
4. Я не стал упоминать порядок декларации переменных, полей, свойств и методов в классах по той причине, что этот момент не сильно влияет читаемость кода. Нужны ли такие избыточные правила в этом стандарте? Не уверен, может кто-то еще выразит свое мнение? Про регионы тоже самое.
Регионы совершенно точно очень положительно влияют на читаемость. Даже если в классе меньше 800 строк (что, кстати, очень много :) удобно, когда можно быстро найти нужный фрагмент.
Порядок декларации преследует те же цели. Я, кстати, использую немного другой:
1). private static поля. Константы.
2). private, protected, protected internal поля (и вообще поля, просто public я использую крайне редко)
3). Конструкторы (от общих к более частным), если есть статический - то ставится в начале списка.
4). Статические свойства, в порядке расширения области доступности
5). Instance-свойства, в порядке расширения области доступности
6). Статические методы, в порядке расширения области доступности
7). Instance-методы, в порядке расширения области доступности
8). Явные реализации интерфейсов (explicit interface implementations), если таковые применяются

Для использования в публикациях это, наверно, не важно, а для собственно программирования — стоит включить, это действительно упрощает жизнь.
Хм, не понимаю когда private и protected выносят в начало... На них так часто внимание обращается? Может лучше public конструкторы, потом public методы, потом public property, а дальше public fields? Хоть сразу видно как работать с объектом... Ну а остальное в удобном порядке по принытому шаблону...
Когда открываешь файл с классом, сразу знаешь, где и что искать. Где поля, где свойства, где методы и т.д. и т.п.
Imho в определении класса сначала лучше писать public члены, т.к. именно они представляют интерес, а не детали реализации - private и protected.
А почему не называть закрытые поля просто через Camel Casing: samplePrivateField? Красивее же...
Потому-что так же называются аргументы методов этого же класса. Придется использовать this, а это лишнее если добавлять префикс.
int pageIndex;
int GetPageIndex(int pageIndex)
{
}
Да, еще. Обязательно нужно писать модификатор доступа.
И любая объявленная переменная или поле должны иметь значение
private List _names = null;
int x = 0;

Понятно, что все знают (или почти все), какое там будет значение по умолчанию, однако, с таким дополнением легче читать код.
согласен с обоими пунктами

2All: кто-нибудь против?
Модификатор тоже считаю нужно указывать явно, а вот значеня переменным не всегда задаю..
Указал обе рекомендации в пункте 2.2
Тема далеко не новая. Все это обычно знает любой более или менее нормальный C# программист.
Не вижу смысла только в этом: - утвердить как стандарт написания C# кода на Хабре =)
Смысл в том, чтобы смотреть на код примеров, которые иногда проскакивают на хабре, и видеть там хороший код.
Примеры, как известно, для того, чтобы учиться, а учиться, как известно, лучше хорошему.
Осталось только убедить пишущих в нужности этого начинания.
Про смысл: смысл есть, когда кода много, его и читать легче, если он написан в знакомой форме. Учитывая, что с форматированием кода на Хабре не самая лучшая ситуация единый стандарт кода - это неплохая вещь, имхо.
Прошу прощения, я не намерен hijack эту дискуссию, но эсли не затруднит, не могли бы вы поделиться впечатлениями какой из двух документов понравился больше - IDesign или наш (SubMain)? Не хочу уводить этот топик в сторону - если не сложно то здесь - http://community.submain.com/forums/9/ShowForum.aspx - можно по русски - я пойму :)

Еще я могу дать бесплатную лицензию на CodeIt.Right - наш тул который проверяет и автоматически исправляет код под стандарты - в обмен на ваши отзывы и мнения.
Признаться удивлен, что здесь есть сотрудники SubMain. Попробую на форуме отписать более развернуто, а пока в двух словах:
- ваш документ описывает кроме всего прочего рекомендации и по vb.
- ваш документ более глубокий, по сравнению с вариантом IDesign и больше походит на стандарт, в то время как вариант IDesign - это в большей степени guidline;
- ваш документ лучше в том смысле, что в темах именования предлагает не только то "что надо делать", но и описывает "то что делать не нужно". Справедливости ради надо заметить, что вариант IDesign так же в большом числе описывает то, чего делать не следует, но это все касается больше уже не именования, а стиля программирования в целом;
- у вас гораздо больше примеров, в то время как вариант IDesign более лаконичный;
- у вас есть таблица стандартного именования префиксов для пользовательских элементов, то о чем сейчас идет дискуссия в этом топике;
- субъективно: в целом, ваш документ более глубок, тогда как IDesign более дружелюбен, если так можно выразиться.
Сотрудники SubMain есть везде :)

SubMain в душе есть русская компания хотя фактически и является американской.

Спасибо за комментарии. Please keep them coming!

Наш документ требует ревизии по части наименования контролов - в текущей версии используются Hungarian notationю
Согласен по основным пунктам. В пункте 3.1 — последний вариант. Предлагаю его же использовать и для protected и protected internal полей-членов класса и статических переменных, согласно рекомендациям по оформлению кода RSDN (http://rsdn.ru/article/mag/200401/codest…).

Рекомендовал бы включить также следующие рекомендации:
1. Используйте пустую строку между логическими секциями в исходном файле, классе, методе
2. Для временных локальных переменных, используемых в коротких участках кода, можно давать имена, состоящие из начальных букв слов имени типа.

... и не применять 2.2 для переменных цикла :)
С пустыми строчками согласен.
Ну и со вторым - LoanTableAdapter lta = new LoanTableAdapter();
1. согласен
2. спорно. Нет, конечно, это удобно, но правильно ли?
3. слава богу 2.2 - это только рекомендация :)
Второй пункт поддерживаю. Это больше для таких "сложных" типов скорее всего подойдет. Как бы формулировку придумать. Это однозначно подходит для типов со сложными названиями, как привел пример AlexS выше. Но для всех ридеров я бы дал имена reader, потоков stream. Для коллекций привязываться к названию типа тоже вроде бы не будешь. Что-то из всего этого так и не придумал как четко рекомендацию сформулировать.. Может кто поможет? :)
Добавил рекомендации в пункт 2.2, постарался описать как можно проще и полнее.
Мне кажется, Сергей имел ввиду
ThisIsLongTypeName tltn = new ThisIsLongTypeName();
Т.е. "что делает" мы не указываем в переменной.
Я так поступаю, когда в текщей области видимости такого типа объявляется только одна переменная.
Ну это частный случай рекомендации, так что вроде все в порядке?
Наверное. Мне тут тяжело просто даже для себя сформулировать это правило, по которому я именую локальные переменные.
>> Но для всех ридеров я бы дал имена reader, потоков stream.
Ага, сам так часто поступаю, в том числе и для команд, например:
SqlCommand command = new SqlCommand();
Но чаще эта методика применяется при именовании формальных параметров метода. На самом деле, тяжело разобраться, как оно там правильно. Замечал, что вариант с префиксами используется в основном для контролов, сокращения от имени типа — в локальных переменных. Но спорить не буду :)
С коммандами и всякими стримами-ридерами поступаю точно также.
+1. У меня очень часто переменная это имя типа с маленькой первой буквой, или просто последнее слово.
Со всем согласен. Огромное спасибо автору за топик. Теперь буду суда новичков посылать чтоб учились хорошому стилю ))
Поддерживаю. :-) Наши coding standards тоже практически полностью совпадают с этими.

Пункт 3.2 насчёт скобок для if можно расширить. Предлагаю разрешить использовать if, for и другие конструкции без скобок (кстати, вы знали, что using тоже можно использовать без скобок?) в случае, если каждая ветвь данного выражения полностью умещается в одну строку:

if (addressAttr != null)
    address = addessAttr.Value;


Если же хотя бы одна ветвь (в данном случае у if) не умещается в одну строку — в фигурные скобки оформляются все ветви, даже else:

if (portAttr != null)
{
    int port;
    if (int.TryParse(portAttr.Value, out port))
        Settings.Port = port;
    else
        throw new Exception("...");
}
else
{
    Settings.Port = DefaultSettings.Port;
}
Ай, проглядел, dmx выше уже предлагал такой вариант…
А руководства от самого MS чем плохи? Кстати если кто знает где эти руководства можно забрать одним файлом подскажите плиз...
Ничем они не плохи. И от RSDN. И даже от SubMain. Просто иметь их под рукой на хабре проще. Да и немного приятнее, что они общие. Наши :)
Мое личное мнение.
Это почти академический труд. Цель данной статьи привести главное в самой простой форме и утвердить это "главное и простое" за норму в теме .net.
Наверно можно как-то декомпилировать из локального MSDN.
Кстати, внутренний naming в самом .NET весьма разнообразен. В ходе продолжительных прогулок с декомпилятором я наблюдал все три варианта именования закрытых полей: и m_field, и field, и _field. И даже _Field :)
Это относится не только к ранним библиотекам, но и к последним продуктам, вроде Linq, ASP.NET MVC, EF... Воистину, привычка свыше нам дана...
Пока готовился к сертификации MS по .net 2.0 пришлось многое изучить. И вот что заметил - разные части фреймворка писали абсолютно разные люди и команды. Это, конечно, понятно. Но порой удивлялся названиям классов :)
Весьма интересно развивается тема оформления кода для .NET
Я интересовался этим в декабре 2007 применительно к оформлению кода на C#, на тот момент мне удалось найти следующие ресурсы (по крайней мере продукты SubMain я тогда не нашел):
Документ от Phillips о конвенциях оформления С# [PDF]
ClockSharp Code Checker
Оба ресурса ведут на сайт организации TIOBE, которая славится своими рейтингами языков программирования.
Спасибо, любопытный документ
Не разьясните, зачем в 2.3 создавать лишнюю временную переменную?
Как то мне кажется читаемость не улучшается от этого (имхо даже ухудшается), а время на создание переменной уходит, и если это будет в большущем цикле, то, думаю, негативно отразится на времени выполнения.
Проще в отладке наверно, я тож так делаю. Особенно если значение перед If ом участвует в каком либо сложном вычислении.
По моему опыту - если больше двух параметров в функции, то уже пора подумать о хэше (структуре).

Пять - это уже далеко за пределами разумного.
Почитайте "Совершенный Код" МакКоннела — 7 параметров максимум (просто потому, что человек не в состоянии удерживать в кратковременной памяти более семи объектов). 5 параметров — вполне себе. 3 — идеально.
Мощная работа проделана автором.

Я для себя использую почти полностью аналогичные правила. Расхождения у меня, например, вот только в именовании закрытых и защищенных полей. Я и те, и другие с префиксовым "_" именую. Ну и скобки фигурные для однострочного ифа редко пользую.
Несколько моментов для рассмотрения:

  • в суффиксы добавить EventHandler - для пользовательских обработчиков

  • выбор коротких имен примитивных типов вместо полных(int, bool вместо Int32, Boolean). Отмечу, что для себя использую всегда короткие имена типов, кроме случаев для целочисленных типов, когда в контексте важен размер переменной.

Еще про обсуждение префиксов или постфиксов в именах контролов. Я использую вариант аналогичный тому, что указал dmx (txtName, lblName). Вариант с полным указанием типа в суффиксе мне не нравится. То есть кнопка в коде должна быть именно кнопкой (btnSearch), неважно является ли она LinkButton, ImageButton или какой-нибудь VeryCoolButton. Потому что префикс я использую именно для указания логики работы контрола, а не типа. И с точки зрения кода нет никакой разницы, выбирается ли элемент из ListBox или из DropDownList; контролы обоих типов я бы назвал как-нибудь типа listHabramen.

И еще вдогонку :) Уже неотносительно топика, так как это вопрос не сильно важный, но мне интересно чужое мнение. Я не так давно думал на тему, когда стоит вместо get-свойства использовать метод Get...() без параметров. Надумал, что единственным случаем, когда следует использовать второй вариант, - чтобы указать что связанное с методом действие является "процессом", то есть может вызвать существенные временные задержки.
Добавил про суффиксы в 1.3
CLR-типы вообще не рекомендуется использовать при программировании и тут вопрос уже не оформления кода, имхо.
Майкрософт вообще-то рекомендует как раз CLR-типы (см. Design Guidelines for Developing Class Libraries, General Naming Conventions в локальной MSDN от .NET SDK или VS). Но в этом конкретном случае я это не поддерживаю. Точнее, я всегда пишу "string s" для переменных, но "String.Format()" для статических методов, аналогично "int i" но "Int32.Parse()" и т.д.
Прошу дать ссылку на то, где Микрософт рекомендует в C# использовать CLR типы.
Из ваших ссылок удалось найти только рекомендации НАЗЫВАТЬ имена методов используя CLR-имена.

For example, a method that converts data to Int16 should be named ToInt16, not ToShort because Short is the language-specific type name for Int16. (c)msdn
Да точно. Память подводит. Значит все нормально.
Именно. Насколько я помню, Design Guidelines от Microsoft именно так и рекомендует. Т.е. предполагается, что свойство должно отрабатывать быстро, сравнимо с доступом к обычной переменной (не всегда конечно есть переменные за каждым свойством, но общая идея такая). Ну и просто нужно учитывать, насколько естественно будет выглядеть обращение к свойству или вызов метода в том или ином контексте.
По поводу последнего. Лично я стараюсь придерживаться этих рекомендаций: http://srtsolutions.com/blogs/billwagner…
Кратко — используйте свойства, если все нижесказанное верно:
— get-аксессоры не содержат сложной логики и не должны вызывать исключения. В них не следует обращаться к базам данных или сетевым ресурсам, так как неудачные попытки могут вызвать исключение.
— Одно свойство не должно зависеть от других. Также, изменение одного свойства не должно влиять на остальные.
— Порядок присвоения (set) может быть любым.
— Вызов get-аксессора не должен иметь заметных побочных эффектов (это не запрещает «ленивых вычислений»).
— get-аксессор должен немедленно возвращать управление. Это исключает возможность использования get-аксессора для обращений к базе данных, web-сервисам и т.д.
— get-аксессор не возвращает массивы.
— повторные вызовы get-аксессора (без изменения прочих условий) возвращают одинаковые значения.
— несколько вызовов set-аксессора с одинаковым аргументом ничем не отличаются от одиночного вызова.
— get-аксессор не должен возвращать ссылку на некие внутренние структуры данных. Можно избежать этого, возвращая «глубокую копию»
избегайте файлов с более чем 500 строками кода;

нервно чешу репу...
а как быть если обстоятельства вынуждают? partial использовать !? ...не понимаю... :")
Это рекомендация, как все рекомендации она не описывает исключительные варианты и предлагает только правило для общих случаев.
тоже верно... просто формулировка забавная ;)
Вставлю свои 2 копейки. Возражения у меня появились, попробую их внятно изложить.

> Pascal casing для констант.

Я для себя решаю так: если константа публична, имя начинается с большой буквы. Если нет, то с маленькой. Если вдруг она перестанет быть константой и превратится в переменную, программу не придётся переписывать (хотя при наличии Refactoring rename это уже не так актуально, как раньше).

> При именовании переменных избегайте использования сокращенных вариантов вроде I и t,
> используйте index и temp. Не используйте венгерскую нотацию или используйте ее только для
> закрытых членов. Не сокращайте слова, используйте number, а не num.

Спорно. По крайей мере, существуют устоявшиеся конструкции, которые одинакого воспринимаются всеми без исключения программистами. Одна из них for(int i = 0; i < limit; i++).

Схватывается целиком. Ну и в целом, есть определённое количество случаев, когда короткие имена понимаются на лету. Постараюсь перечислить:

1. Математические функции. Например sin(T x) или atan2(T y, T x).
2. Целые переменные во вложенных циклах for: i, j, k...
3. Функции с говорящими именами, параметры которых не несут самостоятельного смысла: swap(T a, T b)

Кроме того, в коротких методах с простой структурой, я предпочитаю называть локальные переменные по большим буквам их типа. Например, FileInfo fi, DataReader dr. Ну, и отсюда с необходимостью следуют string s, File f, но только в том случае, если назначение этих переменных очевидно из названия метода.

По поводу num и number согласен.

> используйте промежуточную переменную для передачи bool-значения результата функции в
> условное выражение if;

Такой код для меня однозначно "с запашком" (по Фаулеру). Я обязательно при чтении остановлюсь и начнут думать: зачем сделали именно так? Думаю, эту рекомендацию надо убрать.

> избегайте методов с более чем 200 строками кода;

На мой взгляд, 20 является прекрасной верхней границей. :) Если встречаю большую функцию, рука сама тянется к Refactoring, Extract method. Ключ к читабельности программы вижу в том, что любой метод помещается на экране монитора полностью, тогда все остальные огрехи не так страшны.

> 3.1 Закрытые поля

Сам лично избегаю префиксов и в этом случае тоже. Если внешнее свойство называется Length, закрытая переменная будет называться length. Тут, сам понимаю — момент очень спорный. Тем не менее, считаю, что любые префиксы зло.
Я считаю, что в любом случае, переменная с помощью своего названия должна передавать смысл ее использования. Если используется для координаты - то x, а если это просто поток - то можно использовать и stream.
А вышеуказанные рекомендации - лишь легкий способ создавать осмысленные имена переменным.
Ну и в продолжение темы, отдельным постом для отдельного обсуждения — что ещё можно добавить.

1. Избегать избыточности в именах. Пример: пишем обёртку над ActiveDirectory, пространство имён называем ActiveDirectory. Классы внутри должны назвать User, Group, Computer, а не ADUser, ADGroup, ADComputer.

Второй пример:


class File
{
enum Mode { Read, Write };
}


File.Mode.Read, а не File.FileMode.Read и уж тем более не File.FileMode.ModeRead.

Третий пример, названия методов: File.Open, но не File.OpenFile.

2. Именование множественных объектов. Если есть объект класса T, то коллекцию называем TCollection, список TList. То есть StringCollection, StringList, но не StringsCollection, StringsList. Точно так же предлагаю стыковать имя класса с суффиксом Count: FieldCount, StringCount, FileCount.

Во множественном числе можно называть имена переменных, например FieldCollections fields.

3. Логические переменные, свойства и пр., имеют прифексы is, has: IsDeleted, но не Deleted, HasMoreElements, но не ContainsMoreElements.

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

double velocity = sqrt(sqr(x1 - x2) + sql(y1 - y2))/time;

Должно быть:
double distance = sqrt(sqr(x1 - x2) + sql(y1 - y2));
double velocity = distance/time;

Методы с большим числом параметров, которые не помещаются на одну строку, оформляются так:


. . .
VeryManyArguments(
arg1,
arg2,
arg3,
arg4, // а здесь можно и комментировать
arg5,
arg6,
arg7
);
. . .
Вы предлагаете правила для слишком частных ситуаций, задача этой рекомендации быть компактной и простой. Требовать писать isDeleted не стоит, рекомендовать можно, но тоже лишнее, все это описано в первых двух пунктах и рекомендации 2.1: пишите либо IsDeleted либо isDeleted в зависимости от модификатора доступа.

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

С последним (про методы) лично не согласен, а в контексте правил считаю лишним.
Тогда я просто не понимаю назначение документа. Не могли бы Вы более точно его описать?
Например, почему правило про Exception подходит, а правило про Collection — нет.
а у нас принято ставить скобки в "джава-стиле"...
int DoSmth() {
try {
...
} catch(...) {
}
}

как по мне очень экономит место и улучшает общую читаемость кода.... Глаза не цепляются за лишние строчки.
Удивлялся, как это никто не пишет насчет скобок :)

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

Тут дело, наверное, в том, кто с какого языка перешел на C#.
Ну в моем примере я не могу еще нормально табы расставить :)) все получилось на одном уровне... Я, кстати, еще знаю еще несколько программеров которые между любыми двумя строками кода вставляют еще пустую строку... Кто-то еще так делает? Я вот всегда этого не понимал, а они говорят что удобнее читать... Ужас
Только логические блоки кода разделяю пустой строкой.
Они, наверное, настолько суровы, что у них в каждой строке логический блок кода )))
Подскажите, почему в некоторых примерах MS (например, в 2007 Office System Developer Resources) имена публичных полей написаны с маленькой буквы?

public Guid workflowId = default(System.Guid);
public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties();
В Микрософт тоже живые люди работают, а не роботы как многие думают
:)
Это клиника, господа!!! Зачем вы занимаетесь мозгоебством?!

Кому поможет это стандарт написания ПРИМЕРОВ? Кто его будет использовать? Что, тех кто опубликовал что-то не по стандарту - штрафовать будем? Код ревью на хабре проводить, да? Метрики собирать?

Бред, абсолютный бред.
Это важно! В интернете кто-то неправ! (с)
Предлагаю обязать всех, кто пишет на хабре примеры кода на C#, обязательно снабжать их юнит-тестами!

Давайте немедленно обсудим, проголосуем и утвердим!
Вам то что, дорогая(-ой)? Дайте дядям поиграть в очередную игру.
Насчет констант и static readonly-полей, лично я считаю что старый добрый C-стиль для #define тут более уместен (где все прописные через подчеркивания). Сразу видно что константа, а не свойство или перечисление.
Я до некоторых пор так и делал, тоже от C++ привычка осталась. Но, глядя, на то как оформлен код в том же MSDN задумался, а стоит ли выделяться? Не так уж это и плохо, если константа или элемент перечисления похожи на свойства.
Привычка, в том-то и дело. У меня большинство констант образовались как замена литералам, и они все private. Вобщем за возражение прошу не считать.
UFO just landed and posted this here
А что с новыми возможностями C# 6.0? Особенно много вопросов по свойствам и методам, определяемым через лямбда-выражения. Лично мне кажется, что методы через лямбды приводят с значительному снижению читабельности кода.

Бегло пролистал комменты и не увидел ссылки на это — https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/inside-a-program/coding-conventions


Не хочу быть Колумбом, но вот ваша Америка. Все придумали давно и за вас.


Почему вы используете сокращенные префиксы, но против венгерской нотации? Это вызывает во мне противоречия.


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


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

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

Используйте конструкцию глагол-объект для именования методов

имена делегатов обработчиков событий всегда оканчиваются суффиксом EventHandler


Подскажите, а какую конструкцию использовать для обычных делегатов, не связанных с обработкой событий? Для именования методов глагол-объект. А какую конструкцию использовать для делегатов? Просто добавлять слово Delegate?
Sign up to leave a comment.

Articles