Загальне бачити _var
ім'я змінної у полі класу. Що означає підкреслення? Чи є посилання на всі ці спеціальні угоди про іменування?
Загальне бачити _var
ім'я змінної у полі класу. Що означає підкреслення? Чи є посилання на всі ці спеціальні угоди про іменування?
Відповіді:
Підкреслення - це просто умова; більше нічого. Як таке, його використання завжди дещо різне для кожної людини. Ось як я їх розумію для двох розглянутих мов:
У C ++ підкреслення зазвичай вказує на змінну приватного члена.
У C # я зазвичай бачу, що він використовується лише під час визначення базової змінної приватного члена для публічної власності. Інші змінні приватного члена не мали б підкреслення. Це використання значною мірою пішло убік із появою автоматичних властивостей.
Перед:
private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
Після:
public string Name { get; set; }
public string Name { get; private set; }
. Щоправда, це не зовсім непорушно, але воно є.
_var
не зарезервовано.
Найкраще використовувати НЕ використовувати UNDERSCORES перед будь-яким ім'ям змінної або параметром у C ++
Імена, що починаються з підкреслення або подвійного підкреслення, резервовані для реалізаторів C ++. Імена з підкресленням зарезервовані для роботи бібліотеки.
Якщо ви прочитали в стандарті кодування C ++, ви побачите, що на першій сторінці написано:
"Не переборщуйте іменування, але використовуйте послідовну конвенцію про іменування: Є лише два обов'язкові дози: а) ніколи не використовуйте" невмілих імен ", тих, що починаються з підкреслення або містять подвійне підкреслення;" (p2, стандарти кодування C ++, Herb Sutter та Andrei Alexandrescu)
Більш конкретно, робочий проект ISO визначає фактичні правила:
Крім того, деякі ідентифікатори зарезервовані для використання реалізаціями C ++ і не повинні використовуватися інакше; діагностика не потрібна. (a) Кожен ідентифікатор, який містить подвійне підкреслення __ або починається з підкреслення, за яким йде велика літера, зарезервований для реалізації для будь-якого використання. (b) Кожен ідентифікатор, який починається з підкреслення, зарезервований для реалізації для використання в якості імені в глобальному просторі імен.
Найкраще, щоб уникнути запуску символу з підкресленням, якщо ви випадково переходите на одне з вищезазначених обмежень.
Ви самі бачите, чому таке використання підкреслення може бути згубним при розробці програмного забезпечення:
Спробуйте скласти просту програму helloWorld.cpp так:
g++ -E helloWorld.cpp
Ви побачите все, що відбувається на задньому плані. Ось фрагмент:
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
__streambuf_type* __sb = this->rdbuf();
if (__sb)
{
if (__sb->pubsync() == -1)
__err |= ios_base::badbit;
else
__ret = 0;
}
Ви можете бачити, скільки імен починається з подвійного підкреслення!
Крім того, якщо ви подивитеся на функції віртуальних членів, ви побачите, що * _vptr - це покажчик, сформований для віртуальної таблиці, який автоматично створюється, коли ви використовуєте одну або кілька функцій віртуальних членів у своєму класі! Але це вже інша історія ...
Якщо ви використовуєте підкреслення, ви можете потрапити в конфліктні питання, і ви НЕ ВІДБУДЕТЕ ІДЕЇ, що викликає це, поки не пізно.
Насправді _var
умова походить від VB, а не C # або C ++ (m _, ... інша річ).
Це вдалося подолати нечутливість VB при декларуванні властивостей.
Наприклад, такий код неможливий у VB, оскільки він вважає user
і User
таким самим ідентифікатором
Private user As String
Public Property User As String
Get
Return user
End Get
Set(ByVal Value As String)
user = value
End Set
End Property
Щоб подолати це, деякі використовували конвенцію, щоб додати "_" до приватного поля, щоб прийти таким
Private _user As String
Public Property User As String
Get
Return _user
End Get
Set(ByVal Value As String)
_user = value
End Set
End Property
Оскільки багато конвенцій призначені для .Net і зберігають деяку однаковість між умовами C # et VB.NET, вони використовують ту саму.
Я знайшов посилання на те, що я говорив: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
Справа верблюда з провідним підкресленням. У VB.NET завжди вказуйте "Захищений" або "Приватний", не використовуйте "Дім". Використання "m_" не перешкоджає, як і використання імені змінної, яка відрізняється від властивості лише в окремих випадках, особливо із захищеними змінними, що порушує відповідність, і заподіє вашому життю біль, якщо ви програмуєте в VB.NET, як ви повинен був назвати своїх членів чимось відмінним від властивостей аксесуара / мутатора. З усіх пунктів тут, головне підкреслення дійсно єдине спірне. Я особисто віддаю перевагу над прямим випадком верблюда без підкреслень для моїх приватних змінних, так що мені не доведеться кваліфікувати імена змінних з "це". відрізнити від параметрів у конструкторах чи в інших місцях, де я, швидше за все, матимуть зіткнення імен. З нечутливістю випадку VB.NET це ще важливіше, оскільки властивості вашого доступу зазвичай матимуть те саме ім'я, що і ваші змінні приватного члена, за винятком підкреслення. Що стосується m_, то мова йде саме про естетику. Я (та багато інших) вважаю m_ потворним, оскільки, схоже, є ім'я змінної. Це майже образливо. Я використовував його в VB6 весь час, але це було лише тому, що змінні не могли мати провідного підкреслення. Я не міг бути щасливішим, щоб побачити, як це минає. Microsoft рекомендує проти m_ (і прямого _), навіть якщо вони виконували обидва у своєму коді. Також правильно виходить префіксація з прямим "м". Звичайно, оскільки вони кодують в основному на C #, вони можуть мати приватних членів, які відрізняються лише у випадку, коли вони властивості. Люди з VB повинні робити щось інше. Замість того, щоб спробувати і придумати спеціальні випадки мови, мовні, я рекомендую провідне підкреслення для всіх мов, які його підтримують. Якщо я хочу, щоб мій клас був повністю сумісним із CLS, я можу залишити префікс будь-яких змінних C #, що захищаються. На практиці я, однак, ніколи не переживаю з цього приводу, оскільки зберігаю приватні всі потенційно захищені змінні члена, а натомість постачаю захищені аксесуари та мутатори. Чому: у двох словах, ця умова є простою (один символ), легко читається (очі не відволікаються іншими провідними символами) і успішно уникає імен зіткнення зі змінними на рівні процедури та властивостями рівня класу. Властивості рівня класу . Я рекомендую провідне підкреслення для всіх мов, які його підтримують. Якщо я хочу, щоб мій клас був повністю сумісним із CLS, я можу залишити префікс будь-яких змінних C #, що захищаються. На практиці я, однак, ніколи не переживаю з цього приводу, оскільки зберігаю приватні всі потенційно захищені змінні члена, а натомість постачаю захищені аксесуари та мутатори. Чому: у двох словах, ця умова є простою (один символ), легко читається (очі не відволікаються іншими провідними символами) і успішно уникає імен зіткнення зі змінними на рівні процедури та властивостями рівня класу. Властивості рівня класу . Я рекомендую провідне підкреслення для всіх мов, які його підтримують. Якщо я хочу, щоб мій клас був повністю сумісним із CLS, я можу залишити префікс будь-яких змінних C #, що захищаються. На практиці я, однак, ніколи не переживаю з цього приводу, оскільки зберігаю приватні всі потенційно захищені змінні члена, а натомість постачаю захищені аксесуари та мутатори. Чому: у двох словах, ця умова є простою (один символ), легко читається (очі не відволікаються іншими провідними символами) і успішно уникає імен зіткнення зі змінними на рівні процедури та властивостями рівня класу. Властивості рівня класу . Я ніколи не переживаю з цього приводу, оскільки зберігаю приватні всі потенційно захищені змінні члена, а натомість постачаю захищені аксесуари та мутатори. Чому: у двох словах, ця умова є простою (один символ), легко читається (очі не відволікаються іншими провідними символами) і успішно уникає імен зіткнення зі змінними на рівні процедури та властивостями рівня класу. Властивості рівня класу . Я ніколи не переживаю з цього приводу, оскільки зберігаю приватні всі потенційно захищені змінні члена, а натомість постачаю захищені аксесуари та мутатори. Чому: у двох словах, ця умова є простою (один символ), легко читається (очі не відволікаються іншими провідними символами) і успішно уникає імен зіткнення зі змінними на рівні процедури та властивостями рівня класу. Властивості рівня класу .
Перший коментатор (Р. Самуель Клачко) згадав: Які правила використання підкреслення в ідентифікаторі C ++? який відповідає на питання про підкреслення в C ++. Загалом, ви не повинні використовувати провідне підкреслення, оскільки це зарезервовано для реалізації вашого компілятора. Код, який ви бачите_var
, мабуть, або застарілий код, або код, написаний людиною, яка виросла за допомогою старої системи імен, яка не нахмурилася на провідних підкресленнях.
Як і інші відповіді, він використовувався в C ++ для ідентифікації змінних членів класу. Однак це не має особливого значення, що стосується декораторів чи синтаксису. Тож якщо ви хочете ним скористатися, він складеться.
Я залишу дискусію C # іншим.
_var не має значення і служить лише для того, щоб полегшити розрізнення, що змінна є змінною приватного члена.
У C ++ використання конвенту _var є поганою формою, оскільки існують правила, що регулюють використання підкреслення перед ідентифікатором. _var зарезервовано як глобальний ідентифікатор, тоді як _Var (підкреслення + велика літера) зарезервовано будь-коли. Ось чому в C ++ ви побачите людей, які замість цього використовують конвенцію var_.
Ви можете створити власні вказівки щодо кодування. Просто напишіть чітку документацію для решти команди.
Використання _field допомагає Intelilsense фільтрувати всі змінні класу, просто набравши _.
Я зазвичай дотримуюсь рекомендацій Бреда Адамса , але рекомендую не використовувати підкреслення.
Іменування стандарт Microsoft для C # говорить змінні і параметри повинні використовувати нижню форму верблюд випадку IE: paramName
. Стандарт також вимагає поля , щоб слідувати тій же формі , але це може привести до неясного коду так багато команд вимагають підкреслення префікса для поліпшення ясності IE: _fieldName
.
Що стосується C #, то керівні принципи Microsoft Framework Design рекомендують не використовувати символ підкреслення для публічних членів. Для приватних членів, підкреслення добре використовувати. Насправді, Джеффрі Ріхтер (часто цитується в керівництві), наприклад, використовує m_ і "s_" для приватних статичних членів.
Особисто я використовую просто _ для позначення своїх приватних членів. "m_" та "s_" грань на угорській нотації, яка не тільки нахмурилася в .NET, але може бути досить багатослівною, і мені здається, що класи з багатьма членами складно зробити швидке сканування очей в алфавітному порядку (уявіть 10 змінних, починаючи з m_) .
Я використовую ім'я _var для змінних членів моїх класів. У мене є дві основні причини:
1) Це допомагає мені відстежувати змінні класу та змінні місцевих функцій, коли я читаю свій код пізніше.
2) Це допомагає в Intellisense (або іншій системі заповнення коду), коли я шукаю змінну класу. Просто знання першого символу корисно для фільтрації через список доступних змінних та методів.
Що стосується мов C та C ++, то в імені (початок, середина чи кінець) особливого значення немає. Це просто дійсний символ імені змінної. "Конвенції" походять від практики кодування всередині спільноти кодування.
Як уже вказувалося в різних прикладах вище, _ на початку може означати приватних або захищених членів класу в C ++.
Дозвольте трохи розповісти історію, яка може бути цікавою дрібницею. У UNIX, якщо у вас є функція бібліотеки ядра C та зворотний кінець ядра, де ви хочете піднести функцію ядра до простору користувача, а _ застряг перед заглушкою функції, яка викликає функцію ядра безпосередньо, не роблячи нічого іншого. Найвідоміший і знайомий приклад цього - exit () vs _exit () під ядрами типу BSD та SysV: Там, exit () виконує завдання в просторі користувача перед тим, як викликати службу виходу ядра, тоді як _exit просто відображає службу виходу ядра.
Так _ використовувались для "локальних" речей, у цьому випадку місцеві були машинно-локальними. Зазвичай _functions () не були портативними. При цьому не слід очікувати однакової поведінки на різних платформах.
Тепер, що стосується _ у назвах змінних, таких як
int _foo;
Ну психологічно, _ це дивна річ, яку потрібно набрати на початку. Отже, якщо ви хочете створити ім’я змінної, яке б мало менше шансів зіткнутись із чимось іншим, ОСОБЛИВО, коли ви працюєте із замінами перед процесором, ви хочете розглянути використання _.
Моя основна порада полягає в тому, щоб завжди дотримуватися конвенції вашої спільноти кодування, щоб ви могли ефективніше співпрацювати.
Це просто умова, яку використовують деякі програмісти, щоб зрозуміти, коли ви маніпулюєте членом класу чи якоюсь іншою змінною (параметри, локальні для функції тощо). Ще одна умова, яка також широко використовується для змінних членів, - це префіксація імені "m_".
Так чи інакше, це лише конвенції, і ви не знайдете для них жодного джерела. Вони - питання стилю, і кожна команда програмування, проект чи компанія мають своїх (або навіть не мають).
Є цілком законний привід використовувати його в C #: якщо код також повинен бути розширюваним з VB.NET. (Інакше я б не став.)
Оскільки VB.NET є нечутливим до регістру, field
у цьому коді немає простого способу доступу до захищеного члена:
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
Наприклад, це отримає доступ до власника, а не до поля:
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
Чорт забираю, я навіть не можу писати field
малою літерою - VS 2010 просто виправляє це.
Для того, щоб зробити його доступним для похідних класів у VB.NET, потрібно придумати ще одну умову іменування. Префіксація підкреслення, мабуть, найменш нав'язлива і найбільш «історично прийнята» з них.
Старе запитання, нова відповідь (C #).
Ще одне використання підкреслень для C # - це з використанням DI DI ASP NET Core (введення залежності). Приватні readonly
змінні класу, які присвоюються ін'єктованому інтерфейсу під час побудови, повинні починатися з підкреслення. Я думаю, що це дискусія щодо того, чи використовувати підкреслення для кожного приватного члена класу (хоча сам Microsoft слід за ним), але це точно.
private readonly ILogger<MyDependency> _logger;
public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
}
Конвенція про іменування на зразок цього корисна під час читання коду, особливо коду, який не є вашим власним. Сильна конвенція іменування допомагає вказати, де визначений конкретний член, який він є членом і т. Д. Більшість команд розробників приймають просту конвенцію іменування та просто префіксують поля членів із підкресленням ( _fieldName
). Раніше я використовував таку умову іменування для C # (яка заснована на конвенціях Microsofts для рамкового коду .NET, який можна побачити за допомогою Reflector):
Поле екземпляра: m_fieldName
Статичне поле: s_fieldName
Загальнодоступний / захищений / внутрішній член: PascalCasedName ()
Приватний член: camelCasedName ()
Це допомагає людям зрозуміти структуру, використання, доступність та розташування членів під час читання незнайомого коду дуже швидко.