简体   繁体   English

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

[英]Is there a convention to the order of modifiers in 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. publicprivateprotectedvirtualabstractoverridenewstaticinternalsealed ,以及我忘记的任何其他内容。

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可作为Visual Studio扩展NuGet包提供,并且可以对照Microsoft中某些团队使用的规则来验证您的源代码。 StyleCop likes the access modifier to come first. StyleCop喜欢将访问修饰符放在第一位。

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. 例如,StyleCop建议在命名空间中使用指令,但是Roslyn源代码中并未遵循。

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. 我看了一下Microsoft的《 框架设计指南》 ,找不到关于应在成员上放置哪些顺序修饰符的任何参考。 Likewise, a look at the C# 5.0 language specification proved fruitless. 同样,对C#5.0语言规范的研究也无济于事。 There were two other avenues to follow, though: EditorConfig files and ReSharper . 不过,还有另外两种途径: EditorConfig文件ReSharper


.editorconfig .editorconfig

The MSDN page, .NET coding convention settings for EditorConfig says: MSDN页面, EditorConfig的.NET编码约定设置如下:

In Visual Studio 2017, you can define and maintain consistent code style in your codebase with the use of an EditorConfig file. 在Visual Studio 2017中,您可以使用EditorConfig文件在代码库中定义和维护一致的代码样式。

Example EditorConfig file 示例EditorConfig文件

To help you get started, here is an example .editorconfig file with the default options: 为了帮助您入门,下面是一个带有默认选项的示例.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 

In other words: the default order for modifiers, following the default editorconfig settings is: 换句话说:遵循默认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 锐化器

ReSharper , however, is more forthcoming. 但是, ReSharper即将面世。 The defaults for ReSharper 2018.1 1 , with access modifiers (which are exclusive) and inheritance modifiers (which are exclusive), grouped together is: 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

This is stored in the {solution}.dotsettings file under the 该文件存储在{solution}.dotsettings文件中,位于

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

node - the ReSharper default 2 is: 节点-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>

1 ReSharper 2018.1 says that it has " Full understanding of C# 7.2 " and explicitly mentions the private protected access modifier. 1 ReSharper 2018.1说它具有“ 对C#7.2的充分理解 ”,并明确提到了private protected访问修饰符。

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. 2 ReSharper仅保存与默认设置不同的设置,因此通常在dotsettings文件中看不到该dotsettings


new static vs static new new staticstatic 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 : 编译器警告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; } 

Likewise, the IntelliSense in Visual Studio 2015 also suggests changing static to static new 同样,Visual Studio 2015中的IntelliSense还建议将static更改为static new

CS0108 Visual Studio建议更改

which is the same if the field i in the base class is also static . 如果基类中的字段i也为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 , eg the ReSharper settings for StyleCop GitHub project : 就是说,在GitHub上进行的粗略搜索发现,某些项目会覆盖此默认设置,以便在继承修饰符和sealed 之前而不是 new 之前放置static ,例如, 在StyleCop GitHub项目的ReSharper设置之前

<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). 但是,由于不能将static与继承修饰符或sealed一起使用,因此这只是new static (默认值,由默认的editorconfig文件建议)和static new (由ReSharper建议)之间的区别。

Personally I prefer the latter, but Google searches in referencesource.microsoft.com for new static vs static new in 2015 and 2018 gave: 我个人更喜欢后者,但是Google在referencesource.microsoft.com中搜索了2015年和2018年的new staticstatic new得出:

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

which implies that the preference at Microsoft is static new . 这意味着微软的偏好是static new

I usually start off with the access modifier first, then virtual/abstract/sealed, then override/new/etc. 我通常首先从访问修饰符开始,然后是虚拟/抽象/密封,然后是覆盖/新建/等。 although others might do it differently. 尽管其他人的做法可能有所不同。 Almost invariably, the access modifier will be first, however. 但是,访问修饰符几乎总是不变的。

In some cases there are very many possibilities. 在某些情况下,存在很多可能性。 For example with the below class C with base class B , 例如,对于下面的C类和B类,

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

the field of type DateTime in C has no fewer than five distinct modifiers, so there are 5! == 5*4*3*2*1 == 120 CDateTime类型的字段具有不少于五个不同的修饰符,因此共有5! == 5*4*3*2*1 == 120 5! == 5*4*3*2*1 == 120 different ways to write the same field! 5! == 5*4*3*2*1 == 120种不同的方式写入同一字段! It would be very confusing not to have protected and internal next to each other, but it is still legal. 没有相互protectedinternal毗邻将是非常混乱的,但这仍然是合法的。

Not sure if everyone agrees on a convention for the order. 不确定每个人是否都同意订单约定。 For example I have seen some people put the new modifier before the access level (protection level) modifier, although many people like to always have the protection level modifier first. 比如我看到有些人把new修改的访问级别(保护级)修改之前 ,虽然很多人喜欢总是有保护级别修改第一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM