C#中修饰符的顺序是否有约定?

如果我要使用多个,我应该使用修饰符关键字,例如:

publicprivateprotectedvirtualabstractoverridenewstaticinternalsealed ,以及任何其他我忘了。

如果您下载Microsoft StyleCop Visual Studio插件,它可以根据Microsoft使用的某些团队的规则validation您的源代码。 它首先喜欢访问修饰符。

编辑:微软本身并不完全一致; 不同的团队使用不同的风格 例如。 StyleCop建议在命名空间中使用指令; 但Roslyn源代码中没有遵循这一点。

我看了一下微软的框架设计指南 ,但找不到任何关于应该在成员上添加订单修饰符的参考。 同样,看看C#5.0语言规范也没有结果。 不过还有另外两个途径: EditorConfig文件和ReSharper 。


.editorconfig

用于EditorConfig的MSDN页面, .NET编码约定设置说:

在Visual Studio 2017中,您可以使用EditorConfig文件在代码库中定义和维护一致的代码样式。

示例EditorConfig文件

为了帮助您入门,下面是一个带有默认选项的示例.editorconfig文件:

 ############################### # C# Coding Conventions # ############################### # 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 } // access modifiers static extern new { virtual / abstract / override / sealed override } // inheritance modifiers readonly unsafe volatile async 

ReSharper的

然而, ReSharper更加即将到来。 ReSharper 9.0的默认值,包含访问修饰符(它们是独占的)和inheritance修饰符(它们是独占的),组合在一起是:

 { public / protected / internal / private / protected internal } // 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" 

node – ReSharper默认值1为:

  public protected internal private new abstract virtual sealed override static readonly extern unsafe volatile async  

1 ReSharper仅保存与默认设置不同的设置,因此通常不会在dotsettings文件中看到此节点。


new static vs static new

编译器警告CS0108的MSDN页面给出了基类上的公共字段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; } 

同样,Visual Studio 2015中的IntelliSense也建议将static更改为static new

CS0108 Visual Studio建议更改

如果基类中的字段i也是static ,则相同。

也就是说,对GitHub进行粗略搜索后发现,有些项目会覆盖此默认设置,以便在inheritance修改器和sealed 之前 ,而不是 new 设置 之后放置static ,例如StyleCop GitHub项目的ReSharper设置 :

  public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async  

但是由于static不能与inheritance修饰符一起使用或sealed ,这只是new static (默认的,默认的editorconfig文件建议)和static new (由ReSharper建议)之间的区别。

我个人更喜欢后者,但Google在referencesource.microsoft.com上搜索2015年和2018年的new staticstatic new

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

这意味着微软的偏好是static new

我通常首先使用访问修饰符,然后是虚拟/抽象/密封,然后覆盖/ new / etc。 虽然其他人可能会有不同的做 然而,几乎无一例外,访问修饰符将是第一个。

在某些情况下,有很多可能性。 例如,下面的C类基类B

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

CDateTime类型的字段有不少于五个不同的修饰符,所以有5! == 5*4*3*2*1 == 120 5! == 5*4*3*2*1 == 120种不同的方式来写同一个字段! 如果没有protectedinternal彼此相邻会困惑,但它仍然是合法的。

不确定是否每个人都同意订单的约定。 例如,我看到有些人将new修饰符放在访问级别(保护级别)修饰符之前,尽管许多人喜欢始终首先使用保护级别修饰符。