Существует ли соглашение о порядке модификаторов в C#?

#c#

Вопрос:

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

public , private , protected , virtual , abstract , override , new , static , internal , sealed , и все остальные, о которых я забываю.

Комментарии:

1. Вы пропустили readonly , extern , unsafe , volatile , и async .

Ответ №1:

Я ознакомился с Руководящими принципами разработки фреймворка Microsoft и не смог найти никаких ссылок на то, какие модификаторы порядка следует указывать на участников. Аналогичным образом, взгляд на спецификацию языка C# 5.0 оказался бесплодным. Однако было два других пути: файлы EditorConfig и ReSharper.


.редактор

На странице MSDN в настройках соглашения о кодировании .NET для EditorConfig говорится:

В Visual Studio 2017 вы можете определить и поддерживать согласованный стиль кода в своей кодовой базе с помощью файла EditorConfig.

Пример файла EditorConfig

Чтобы помочь вам начать работу, вот пример файла .editorconfig с параметрами по умолчанию:

 ###############################
# C# Code Style Rules         #
###############################

# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
 

Другими словами: порядок по умолчанию для модификаторов, следующий за настройками editorconfig по умолчанию:

 { public / private / protected / internal / protected internal / private protected } // access modifiers
static
extern
new
{ virtual / abstract / override / sealed override } // inheritance modifiers
readonly
unsafe
volatile
async
 

Решарпер

Решарпер, однако, более откровенен. Значения по умолчанию для ReSharper 2018.1 1 с модификаторами доступа (которые являются эксклюзивными) и модификаторами наследования (которые являются эксклюзивными), сгруппированными вместе, составляют:

 { public / protected / internal / private / protected internal / private protected } // access modifiers
new
{ abstract / virtual / override / sealed override } // inheritance modifiers
static
readonly
extern
unsafe
volatile
async
 

Это хранится в {solution}.dotsettings файле под

 "/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue"
 

узел — решарпер по умолчанию 2 равен:

 <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue">
    public protected internal private new abstract virtual sealed override static readonly extern unsafe volatile async
</s:String>
 

ReSharper 2018.1 1 говорит, что он «Полностью понимает C# 7.2» и явно упоминает модификатор private protected доступа.

2 ReSharper сохраняет только настройки, отличные от настроек по умолчанию, поэтому в целом этот узел, как он есть, не будет отображаться в dotsettings файле.


new static против static new

На странице MSDN для предупреждения компилятора CS0108 приведен пример открытого поля i в базовом классе, скрытого общедоступным статическим полем i в производном классе: их предложение состоит в том, чтобы изменить static на static new :

 public class clx
{
    public int i = 1;
}

public class cly : clx
{
    public static int i = 2; // CS0108, use the new keyword
    // Use the following line instead:
    // public static new int i = 2;
}
 

Аналогично, IntelliSense в Visual Studio 2015 также предлагает перейти static на static new

CS0108 Visual Studio рекомендуется изменить

что то же самое, если поле i в базовом классе также static .

Тем не менее, беглый поиск на GitHub показал, что некоторые проекты переопределяют это значение по умолчанию, чтобы ставить модификаторы наследования static до , а не после new , и sealed , например, параметры настройки для проекта StyleCop GitHub:

 <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue">
    public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async
</s:String>
 

однако , поскольку static не может использоваться в сочетании с модификаторами наследования или sealed , это просто различие между new static (по умолчанию и предложено файлом editorconfig по умолчанию) и static new (предложено ReSharper).

Лично я предпочитаю последнее, но поиск в Google в referencesource.microsoft.com для new static vs static new в 2015 и 2018 годах дали:

              (in 2015)  (in 2018)
new static   203        427
static new   10         990
 

что подразумевает, что предпочтение в Microsoft является static new .

Комментарии:

1. Это должен быть выбранный ответ по состоянию на 2019 год

Ответ №2:

StyleCop доступен в виде расширения Visual Studio или пакета NuGet и может проверять ваш исходный код на соответствие правилам, которые используют некоторые команды Microsoft. StyleCop любит, чтобы модификатор доступа был на первом месте.

ПРАВКА: Microsoft сама по себе не полностью последовательна; разные команды используют разные стили. Например, StyleCop предлагает поместить директивы using в пространство имен, но в исходном коде Roslyn этого не следует.

Комментарии:

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

2. В StyleCop есть правила, которые, похоже, отличаются от предыдущих руководств по стилю MS. Например, StyleCop ненавидит m_ и _ за приставки к закрытым членам. Кроме того, генерация кода VS по умолчанию нарушает StyleCop, помещая операторы using за пределы пространства имен. вздыхать

3. В качестве подсказки: Сортировка всего беспорядка может быть очень раздражающей, если раньше у вас была другая структура классов. Используйте CodeMaid, который может сделать это автоматически.

4. У меня сложилось впечатление, что операторы using ведут себя по-разному в зависимости от того, куда вы их помещаете.

Ответ №3:

Обычно я начинаю сначала с модификатора доступа, затем виртуального/абстрактного/запечатанного, затем переопределяю/новый/и т. Д., Хотя другие могут сделать это по-другому. Однако почти всегда модификатор доступа будет первым.

Ответ №4:

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

 public class B
{
  public void X()
  {
  }
}
public class C : B
{
  protected internal new static readonly DateTime X;
}
 

поле ввода DateTime C имеет не менее пяти различных модификаторов, поэтому существуют 5! == 5*4*3*2*1 == 120 разные способы записи одного и того же поля! Было бы очень запутанно не иметь protected и internal рядом друг с другом, но это все еще законно.

Не уверен, что все согласны с соглашением для заказа. Например, я видел, как некоторые люди ставят new модификатор перед модификатором уровня доступа (уровень защиты), хотя многим людям нравится всегда иметь модификатор уровня защиты первым.