Есть ли соглашение о порядке модификаторов в С#?
Если бы мне пришлось использовать несколько экземпляров, какой порядок я должен использовать в качестве ключевых слов-модификаторов, например:
public
, private
, protected
, virtual
, abstract
, override
, new
, static
, internal
, sealed
и любые другие, которые я забываю.
Ответы
Ответ 1
StyleCop доступен в виде расширения Visual Studio или пакета NuGet и может проверять ваш исходный код на соответствие правилам, используемым некоторыми командами Microsoft. StyleCop нравится модификатор доступа, который стоит первым.
РЕДАКТИРОВАТЬ: Microsoft сама не является полностью последовательной; разные команды используют разные стили. Например, StyleCop предлагает поместить директивы using в пространство имен, но в исходном коде Roslyn этого не происходит.
Ответ 2
Я взглянул на Руководство по проектированию Microsoft Framework и не смог найти никаких ссылок на то, какие модификаторы порядка должны быть наложены на участников. Аналогично, просмотр спецификации языка С# 5.0 оказался бесплодным. Тем не менее, есть два других пути: файлы EditorConfig и ReSharper.
.editorconfig
Страница 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
Другими словами: порядок по умолчанию для модификаторов, следующий за настройками по умолчанию:
{ 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
ReSharper, однако, является более предстоящим. Значения по умолчанию для 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"
узел - ReSharper по умолчанию 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>
1ReSharper 2018.1 говорит, что у него "Полное понимание С# 7.2" и явно упоминает модификатор private protected
доступа.
2 ReSharper сохраняет только настройки, которые отличаются от настроек по умолчанию, поэтому в целом этот узел, как он есть, не будет dotsettings
файле 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 recommended change]()
что то же самое, если поле i
в базовом классе также является static
.
Тем не менее, беглый поиск в GitHub обнаружил, что некоторые проекты переопределяют это значение по умолчанию для установки static
до, а не после new
, модификаторов наследования и sealed
, например, настройки ReSharper для проекта 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 ищет на сайте sourcesource.microsoft.com new static
и static new
в 2015 и 2018 годах:
(in 2015) (in 2018)
new static 203 427
static new 10 990
что подразумевает, что предпочтение в Microsoft является static new
.
Ответ 3
Обычно я начинаю сначала с модификатора доступа, затем с виртуального/абстрактного/закрытого, затем переопределяю/new/и т.д. хотя другие могут сделать это по-другому. Однако почти всегда модификатор доступа будет первым.
Ответ 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
до модификатора уровня доступа (уровня защиты), хотя многим людям нравится всегда иметь модификатор уровня защиты.