C#中修饰符的顺序是否有惯例?

36
如果我要使用多个关键字修饰词,应该按照什么顺序来使用呢?包括以下关键字:publicprivateprotectedvirtualabstractoverridenewstaticinternalsealed等。

2
你错过了readonlyexternunsafevolatileasync - Wai Ha Lee
5个回答

36

我查看了Microsoft的Framework Design Guidelines,但没有找到有关成员修饰符应该放置在什么顺序的参考文献。同样地,查看C# 5.0语言规范也没有结果。不过还有两个方向可以跟进:EditorConfig文件ReSharper


.editorconfig

MSDN页面 .NET coding convention settings for EditorConfig 中写道:

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
换言之,按照默认的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更为直接。ReSharper 2018.11的默认设置,包括访问修饰符(互斥)和继承修饰符(互斥),分组如下:

{ public / protected / internal / private / protected internal / private protected } // 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 的默认设置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.

1 ReSharper 2018.1 表示它具有“完全理解 C# 7.2”,并明确提到了 private protected 访问修饰符。

2.

2 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中的智能感知建议将static更改为static new

CS0108 Visual Studio recommended change

如果基类中的字段i也是static,那么这与new关键字后面加static是一样的。

话虽如此,在GitHub上进行了粗略搜索发现,有些项目覆盖了这个默认设置,将static放在new关键字之前而不是之后,继承修饰符和sealed之后,例如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>

然而由于static不能与继承修饰符或sealed一起使用,因此这只是new static(默认值,并由默认的editorconfig文件建议)和static new(由ReSharper建议)之间的区别。

个人偏好后者,但在2015年和2018年的referencesource.microsoft.com中对new staticstatic new的Google搜索结果如下:

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

这意味着微软偏好使用 static new

3
2019年时,这应该是被选中的答案。 - mins

22

StyleCop 可以作为Visual Studio扩展程序NuGet软件包提供,可针对一些微软团队使用的规则验证您的源代码。StyleCop 喜欢访问修饰符 (access modifier) 放在第一位。

编辑说明: 微软本身并不完全一致; 不同的团队使用不同的风格。例如,StyleCop建议将using指令放在命名空间(namespace)中,但这在Roslyn源代码中并未遵循。


2
非常好的回答。尽可能地让像 StyleCop 这样的工具来监控代码风格规范的遵循,因为它比我们这些普通人要可靠得多 :) - David Arno
2
StyleCop有一些规则似乎与微软以前的样式指南不同。例如,StyleCop不喜欢将m_和_用作私有成员的前缀。此外,VS默认代码生成违反了StyleCop的规定,因为它将using语句放在命名空间之外。叹气 - CrashCodes
1
作为一个提示:如果你之前有另一种类的结构,整理这个混乱的代码可能会非常烦人。使用CodeMaid可以自动完成这个任务。 - Christian Sauer
2
我曾经认为,使用语句的行为取决于它们放置的位置。 - Kyle Delaney

3

我通常先处理访问修饰符,然后是虚拟/抽象/密封,最后是重写/新建等。虽然其他人可能会有不同的做法,但几乎总是要先处理访问修饰符。


1
在某些情况下,可能会有非常多的可能性。例如,对于以下具有基类B的类C
public class B
{
  public void X()
  {
  }
}
public class C : B
{
  protected internal new static readonly DateTime X;
}

在C语言中,类型为DateTime的字段至少有五个不同的修饰符,因此有120种不同的编写方式!如果没有将protected和internal放在一起,那将会非常令人困惑,但这仍然是合法的。并不确定每个人是否都同意一个约定的顺序。例如,我见过一些人在访问级别(保护级别)修饰符之前放置new修饰符,尽管许多人喜欢始终将保护级别修饰符放在第一位。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接