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

时间:2022-02-12 05:28:26

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.

公共,私人,受保护,虚拟,抽象,覆盖,新,静态,内部,密封,以及任何其他我忘了。

4 个解决方案

#1


18  

If you download the Microsoft StyleCop Visual Studio addin, it can validate your source code against the rules some teams in Microsoft use. It likes the access modifier to come first.

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

EDIT: Microsoft isn't itself totally consistent; different teams use different styles. Eg. StyleCop suggests putting using directives in the namespace; but this is not followed in the Roslyn source code.

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

#2


10  

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.

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


.editorconfig

The MSDN page, .NET coding convention settings for EditorConfig says:

用于EditorConfig的MSDN页面,.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

To help you get started, here is an example .editorconfig file with the default options:

为了帮助您入门,下面是一个带有默认选项的示例.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

In other words: the default order for modifiers, following the default editorconfig settings is:

换句话说:在默认的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, however, is more forthcoming. The defaults for ReSharper 9.0, with access modifiers (which are exclusive) and inheritance modifiers (which are exclusive), grouped together is:

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

{ public / protected / internal / private / protected internal } // 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 default1 is:

node - ReSharper default1是:

<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 only saves settings which differ from the default, so in general this node, as it is, will not be seen in the dotsettings file.

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


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:

编译器警告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也建议将静态更改为静态新

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

which is the same if the field i in the base class is also static.

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

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:

也就是说,对GitHub进行粗略搜索后发现,有些项目会覆盖此默认值,以便在继承修改器之前而不是在新的之后放置静态,并将其保密。 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).

但是由于静态不能与继承修饰符一起使用或密封,这只是新静态(默认的,默认的editorconfig文件建议)和静态的新(由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年的新静态与静态新内容:

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

which implies that the preference at Microsoft is static new.

这意味着微软的偏好是静态新的。

#3


3  

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.

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

#4


1  

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 different ways to write the same field! It would be very confusing not to have protected and internal next to each other, but it is still legal.

C语言中DateTime类型的字段有不少于五个不同的修饰符,所以有5个! == 5 * 4 * 3 * 2 * 1 == 120种不同的方式来写同一个字段!如果没有保护和内部彼此相邻会很困惑,但它仍然是合法的。

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.

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

#1


18  

If you download the Microsoft StyleCop Visual Studio addin, it can validate your source code against the rules some teams in Microsoft use. It likes the access modifier to come first.

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

EDIT: Microsoft isn't itself totally consistent; different teams use different styles. Eg. StyleCop suggests putting using directives in the namespace; but this is not followed in the Roslyn source code.

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

#2


10  

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.

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


.editorconfig

The MSDN page, .NET coding convention settings for EditorConfig says:

用于EditorConfig的MSDN页面,.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

To help you get started, here is an example .editorconfig file with the default options:

为了帮助您入门,下面是一个带有默认选项的示例.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

In other words: the default order for modifiers, following the default editorconfig settings is:

换句话说:在默认的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, however, is more forthcoming. The defaults for ReSharper 9.0, with access modifiers (which are exclusive) and inheritance modifiers (which are exclusive), grouped together is:

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

{ public / protected / internal / private / protected internal } // 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 default1 is:

node - ReSharper default1是:

<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 only saves settings which differ from the default, so in general this node, as it is, will not be seen in the dotsettings file.

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


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:

编译器警告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也建议将静态更改为静态新

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

which is the same if the field i in the base class is also static.

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

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:

也就是说,对GitHub进行粗略搜索后发现,有些项目会覆盖此默认值,以便在继承修改器之前而不是在新的之后放置静态,并将其保密。 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).

但是由于静态不能与继承修饰符一起使用或密封,这只是新静态(默认的,默认的editorconfig文件建议)和静态的新(由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年的新静态与静态新内容:

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

which implies that the preference at Microsoft is static new.

这意味着微软的偏好是静态新的。

#3


3  

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.

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

#4


1  

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 different ways to write the same field! It would be very confusing not to have protected and internal next to each other, but it is still legal.

C语言中DateTime类型的字段有不少于五个不同的修饰符,所以有5个! == 5 * 4 * 3 * 2 * 1 == 120种不同的方式来写同一个字段!如果没有保护和内部彼此相邻会很困惑,但它仍然是合法的。

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.

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