Чтобы подчеркнуть или не подчеркнуть, это вопрос

Есть ли проблемы с префиксами частных полей с подчеркиванием на С#, если бинарная версия будет потребляться другими языками Framework? Например, поскольку С# чувствителен к регистру, вы можете вызвать поле "foo" и общедоступное свойство "Foo", и оно отлично работает.

Будет ли это иметь какой-либо эффект на нечувствительном к регистру языке, таком как VB.NET, будут ли выполняться какие-либо проблемы с CLS-совместимостью (или другими), если имена могут быть различимы только оболочкой?

Ответ 1

У этого эффекта будет нет.

Часть рекомендаций для написания библиотек, совместимых с CLS, состоит в том, что у НЕ должно быть два общедоступных/защищенных объекта, которые отличаются только по конкретному случаю, например, вы должны НЕ иметь

public void foo() {...}

и

public void foo() {...}

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

Ответ 2

ВАЖНОЕ ОБНОВЛЕНИЕ (12 апреля 2016 года):

Было обращено на наше внимание, что внутренний стандарт команды .NET CoreFX настаивает на использовании подчеркивания-нотации, не давая никаких сведений, как почему. Однако, если мы внимательно рассмотрим правило № 3, становится очевидным, что существует система префиксов _, t_, s_, которая предполагает, почему в первую очередь выбрано _.

  1. Мы используем _camelCase для внутренних и частных полей и используем readonly, где это возможно. Поля экземпляра префикса с _, статические поля с s_ и статические поля потока с помощью t_. При использовании в статических полях readonly должен появиться после static (т.е. static readonly не readonly static).
  2. Мы избегаем this., если это абсолютно необходимо.

Итак, если вы похожи на команду .NET CoreFX, работающую над некоторым критичным для производительности, многопоточным, системным кодом, тогда СИЛЬНО ПРЕДЛАГАЕТ, что вы:

  • придерживаться своих стандартов кодирования и
  • используйте подчеркивание и
  • больше не читайте этот ответ

В противном случае, пожалуйста, прочитайте...

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Позвольте сначала согласиться с тем, о чем мы говорим. Вопрос заключается в том, как мы получаем доступ к членам экземпляра из нестатических методов и конструкторов класса/подклассов, если модификаторы видимости позволяют это сделать.

Подчеркивание-обозначения

  • предполагает, что вы используете префикс "_" в именах частных полей
  • он также говорит, что вы никогда не должны использовать "this", если это абсолютно необходимо

Это-обозначения

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

Почему существует эта нотация?

Потому что так вы

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

Пример

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}

Почему существует обозначение подчеркивания?

Некоторым людям не нравится набирать "this", но они по-прежнему нуждаются в возможности различать поле и параметр, поэтому они согласились использовать "_" перед полем

Пример

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}

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

Ясность

  • Недопустимые имена нот обозначений
  • эта-нотация сохраняет имена неповрежденными

Когнитивная нагрузка

  • подчеркивание-нотация несовместимо, это заставляет вас обрабатывать поля особым образом, но вы не можете использовать его с другими членами, каждый раз, когда вам нужно спросить себя, нужно ли вам свойство или поле

  • эта-нотация последовательна, вам не нужно думать, вы просто всегда используете "this" для ссылки на любой член

Обслуживание

  • подчеркивание-примечание требует, чтобы вы следили за _ во время рефакторинга, скажем, превращая поле в свойство (удалить _) или наоборот (add _)

  • эта-нотация не имеет такой проблемы

Автозаполнение

Когда вам нужно увидеть список членов экземпляра:

  • underscore-notation вам не поможет, потому что, когда вы вводите "_", всплывающее окно автозаполнения показывает частные поля и все типы, доступные из связанных сборок, смешанных с остальными членами экземпляра.
  • это -значение дает вам четкий ответ, набрав "this" все, что вы видите, это список участников и ничего больше

Неоднозначность

Иногда вам приходится иметь дело с кодом без помощи Intellisense. Например, когда вы просматриваете код или просматриваете исходный код онлайн.

  • подчеркивание-обозначение неоднозначно: когда вы видите Something.SomethingElse, вы не можете определить, является ли Something классом, а SomethingElse - его статическим свойством... или, возможно, что-то является свойством текущего экземпляра, которое имеет собственное свойство SomethingElse

  • this-notation is clear: Когда вы видите Something.SomethingElse, это может означать только класс со статическим свойством и когда вы видите это. Что-то. Что-тоElse вы знаете, что что-то является членом, а SomethingElse - его свойством

Методы расширения

Вы не можете использовать методы расширения в самом экземпляре, не используя "this."

  • underscore-notation требует, чтобы вы не использовали "this", однако с помощью методов расширения, которые вы должны
  • эта-нотация избавляет вас от колебаний, вы всегда используете "this", период.

Поддержка Visual Studio

  • underscore-notation не имеет встроенной поддержки в Visual Studio
  • эта нотация поддерживается Visual Studio естественно:

Официальные рекомендации

Там много официальных рекомендаций, в которых четко сказано "не использовать подчеркивания", особенно в С#

Ответ 3

Взято из файла справки Microsoft StyleCop:

TypeName:  FieldNamesMustNotBeginWithUnderscore

CheckId:  SA1309

Причина: Имя поля в С# начинается с подчеркивания.

Описание правила:

Нарушение этого правила происходит, когда имя поля начинается с подчеркивания.

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

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

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

Изменить: В качестве последующих шагов страница проекта StyleCop находится здесь: http://code.msdn.microsoft.com/sourceanalysis. Чтение файла справки дает много понимания того, почему они предлагают различные стилистические правила.

Ответ 4

Поскольку мы говорим о частном поле, это не влияет на пользователя вашего класса.

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

private int foo;
public void SetFoo(int foo)
{
  // you have to prefix the private field with "this."
  this.foo = foo;

  // imagine there lots of code here,
  // so you can't see the method signature



  // when reading the following code, you can't be sure what foo is
  // is it a private field, or a method-argument (or a local variable)??
  if (foo == x)
  {
    ..
  }
}

В нашей команде мы всегда используем префикс подчёркивания для частных полей. Таким образом, при чтении некоторого кода я могу легко идентифицировать частные поля и рассказать им отдельно от локальных и аргументов. В некотором смысле подчеркивание можно рассматривать как сокращенную версию "this".

Ответ 5

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

Я ненавижу ключевое слово this., это просто добавляет слишком много шума кода, на мой взгляд. Мне нравится Resharper удалить лишнее это. ключевое слово.

6-летнее обновление: Я анализировал внутренние элементы Dictionary<TKey,T> для конкретного использования параллельного доступа и неправильно читал приватное поле как локальную переменную. Частные поля определенно не должны быть одним и тем же соглашением об именах, что и локальные переменные. Если бы был символ подчеркивания, это было бы невероятно очевидно.

Ответ 6

Мне нравится подчеркивание, потому что тогда я могу использовать строчное имя в качестве параметров метода, например:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}

Ответ 7

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

Однако в последнее время я нахожу, что использование префикса подчеркивания для частных членов неодобрительно, хотя я не совсем уверен, почему. Может, кто-то еще знает? Это только принцип префикса? Или было что-то связанное с изменением имени родовых типов, которые получают в них символы подчеркивания в скомпилированных сборках или что-то в этом роде?

Ответ 8

Рекомендация Style Cop или нет, выкапывание в .NET Framework показывает много "_" использования для переменных-членов. Независимо от того, что создатели Style Cop рекомендуют, это не то, что большинство сотрудников MS используют.:) Поэтому я буду придерживаться подчеркивания. Поскольку я лично делаю намного меньше ошибок с помощью подчеркивания, тогда это (пример: using varName = varName вместо this.varName = varName, это действительно застряло во мне)

Ответ 9

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

public int Foo
{
   private int foo;
   get
   {
      return foo;
   }
   set
   {
      foo = value;
   }
}

Это позволит полностью прекратить использование полей.

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

Ответ 10

Если вы хотите, чтобы ваша сборка была совместимой с CLS, вы можете использовать атрибут CLSCompliant в файле assemblyinfo. Затем компилятор будет жаловаться, когда ваш код содержит материалы, не совместимые с cls.

Затем, когда у вас есть 2 свойства, которые отличаются только в случае, компилятор выдаст ошибку. С другой стороны, когда у вас есть частное поле и общедоступное свойство в том же классе, проблем не будет.

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

Ответ 11

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

Ответ 12

Обозначение _fieldName для закрытых полей настолько легко разбить. Использование "этого". обозначение невозможно сломать. Как бы вы нарушили обозначение? Обратите внимание:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}

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

Контрастируйте это с Ruby, где имя переменной @my_number связывает это имя с областью действия и нерушимо.

edit: Этот ответ пошел отрицательно. Мне все равно, он остается.

Ответ 13

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