Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a convention to the order of modifiers in C#?

Tags:

c#

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.

like image 802
CrashCodes Avatar asked Oct 10 '08 15:10

CrashCodes


People also ask

Are there any access modifiers in C?

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.

What are class access modifiers?

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.


2 Answers

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.


.editorconfig

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

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

CS0108 Visual Studio recommended change

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.

like image 75
Wai Ha Lee Avatar answered Sep 21 '22 23:09

Wai Ha Lee


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.

like image 35
Mark Heath Avatar answered Sep 21 '22 23:09

Mark Heath