If I were to use more than one, what order should I use modifier keywords such as:
public
, private
, protected
, virtual
, abstract
, override
, new
, static
, internal
, sealed
, and any others I'm forgetting.
public : Access is not restricted. protected : Access is limited to the containing class or types derived from the containing class. internal : Access is limited to the current assembly. protected internal : Access is limited to the current assembly or types derived from the containing class.
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.
I had a look at Microsoft's Framework Design Guidelines and couldn't find any references to what order modifiers should be put on members. Likewise, a look at the C# 5.0 language specification proved fruitless. There were two other avenues to follow, though: EditorConfig files and ReSharper.
The MSDN page, .NET coding convention settings for EditorConfig says:
In Visual Studio 2017, you can define and maintain consistent code style in your codebase with the use of an EditorConfig file.
Example EditorConfig file
To help you get started, here is an example .editorconfig file with the default options:
############################### # 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
In other words: the default order for modifiers, following the default editorconfig settings is:
{ 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, however, is more forthcoming. The defaults for ReSharper 2018.11, with access modifiers (which are exclusive) and inheritance modifiers (which are exclusive), grouped together is:
{ public / protected / internal / private / protected internal / private protected } // access modifiers new { abstract / virtual / override / sealed override } // inheritance modifiers static readonly extern unsafe volatile async
This is stored in the {solution}.dotsettings
file under the
"/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue"
node - the ReSharper default2 is:
<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 says that it has "Full understanding of C# 7.2" and explicitly mentions the private protected
access modifier.
2 ReSharper only saves settings which differ from the default, so in general this node, as it is, will not be seen in the dotsettings
file.
new static
vs static new
The MSDN page for Compiler Warning CS0108 gives the example of a public field i
on a base class being hidden by a public static field i
on a derived class: their suggestion is to change static
to 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; }
Likewise, the IntelliSense in Visual Studio 2015 also suggests changing static
to static new
which is the same if the field i
in the base class is also static
.
That said, a cursory search on GitHub found that some projects override this default to put static
before, not after new
, the inheritance modifiers and sealed
, e.g. the ReSharper settings for StyleCop GitHub project:
<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>
however since static
cannot be used in conjunction with the inheritance modifiers or sealed
, this is just a distinction between new static
(the default, and suggested by the default editorconfig file) and static new
(suggested by ReSharper).
Personally I prefer the latter, but Google searches in referencesource.microsoft.com for new static
vs static new
in 2015 and 2018 gave:
(in 2015) (in 2018) new static 203 427 static new 10 990
which implies that the preference at Microsoft is static new
.
StyleCop is available as a Visual Studio extension or a NuGet package and can validate your source code against the rules some teams in Microsoft use. StyleCop likes the access modifier to come first.
EDIT: Microsoft isn't itself totally consistent; different teams use different styles. For example StyleCop suggests putting using directives in the namespace, but this is not followed in the Roslyn source code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With