类中的项目顺序:字段,属性,构造函数,方法

mmc*_*ole 596 .net c# coding-style code-cleanup code-structure

在课程结构方面,是否有关于项目顺序的官方C#指南?

它会去:

  • 公共领域
  • 私人领域
  • 属性
  • 构造函数
  • 方法

我很好奇是否有关于物品顺序的硬性规定?我到处都是.我想坚持一个特定的标准,所以我可以到处做.

真正的问题是我的更复杂的属性最终看起来很像方法,他们觉得在构造函数之前顶部不合适.

有什么提示/建议吗?

Jon*_*ght 880

根据StyleCop规则文档,订购如下.

在类,结构或接口中:(SA1201和SA1203)

  • 恒定场
  • 字段
  • 构造函数
  • 终结者(Destructors)
  • 代表
  • 活动
  • 枚举
  • 接口(接口实现)
  • 属性
  • 索引
  • 方法
  • 结构

在每个组中按访问顺序排列:(SA1202)

  • 上市
  • 内部
  • 保护内部
  • 保护
  • 私人的

在每个访问组中,按静态排序,然后是非静态:(SA1204)

  • 静态的
  • 非静态

在每个静态/非静态字段组中,按readonly排序,然后是非readonly:(SA1214和SA1215)

  • 只读
  • 非只读

展开的列表是130行,所以我不会在这里展开它.部分展开的方法是:

  • 公共静态方法
  • 公共方法
  • 内部静态方法
  • 内部方法
  • 受保护的内部静态方法
  • 保护内部方法
  • 保护静态方法
  • 保护方法
  • 私有静态方法
  • 私人方法

该文档指出,如果规定的顺序不合适 - 例如,正在实现多个接口,并且接口方法和属性应该组合在一起 - 那么使用部分类将相关的方法和属性组合在一起.

  • 就个人而言,我发现静态方法的排序很烦人.我可以看到静态公共方法的参数首先出现,但我通常希望在成员之后使用私有静态方法.毕竟他们是公用事业. (42认同)
  • 我要感谢你在这篇文章中付出努力.我试图让StyleCop的东西成为标准(即使只是为了保持一致并且很容易找到东西),这很有价值. (27认同)
  • 我喜欢部分课程提示 (13认同)
  • 只是关于部分课程的说明.鉴于在编译期间所有部分都被编译成单个类型,我总是会尝试确保创建额外开销的充分理由.部分类的主要原因是扩展自动生成源代码或在处理大型项目时允许多个开发人员在同一个类上工作但是单独的文件. (6认同)
  • @FrançoisWahl与编译器相关的开销是否将部分类组合成一个大的单一类型? (3认同)
  • @FrançoisWahl我认为开销不是太糟糕,从长远来看,可读性的好处将为您节省更多时间:)有趣的文章 - 我没有意识到存在部分方法! (3认同)
  • 有了“新” C#自动属性,我真的不喜欢字段->构造函数->属性顺序,如果只有1或2个属性,我觉得这些属性应该排在字段之后。虽然很难将“一两个”作为确定的规则,所以我一直遵循这一原则... (3认同)
  • @dav_i:我真的不知道开销是否明显,我还没有对此进行任何性能测试。它很可能并不引人注目,但作为一般经验法则,我尝试仅在扩展自动生成的代码时创建部分代码。这里还有一个关于部分的很好的资源:http://www.4guysfromrolla.com/articles/071509-1.aspx (2认同)
  • 我避免的唯一一件事就是拆分字段及其相关的访问器属性.我认为这种对是一个领域. (2认同)
  • “接口”(枚举和属性之间)是什么意思?显式接口实现还是...? (2认同)
  • @FrançoisWahl - 我在大型项目中经常使用部分类。我注意到绝对没有编译开销,最大的项目大约有 60 万行。我不喜欢一个有几十个访问器和方法的类。在大型课程中,我会将其拆分为单独的 .cs 文件,每个方法一个。我发现这也使得查看解决方案资源管理器并立即直观地查看类中的所有可用方法变得更加简单,而不必打开文件并浏览它。 (2认同)

Rya*_*ndy 32

而不是通过可见性或项目类型(字段,属性,方法等)进行分组,而不是按功能分组?

  • 如果你的课程中有很多方法,属性等,你需要按部分对它们进行分组,也许这表明课程做得太多了? (66认同)
  • 按功能分组称为类 (52认同)
  • 如果公共方法Foo()调用受保护/私有的InternalFoo(),那么第二种方法更好地位于源中的DoFoo()之下,而不是其他受保护/私有方法中的其他位置. (9认同)
  • 即使该类很小,将公共方法与其相应的私有方法分组也不合理,这些方法只能通过这种公共方法调用? (8认同)
  • 如果使用StyleCop建议进行"排序",则它是一种功能.有些方法是公开的,而其他方法是私有的,这是有充分理由的.代码实际上更易读:如果打开一个类的.cs文件,我会立即看到公共方法比私有方法"更重要"(对于那个使用该类的人) (2认同)

bri*_*ght 21

这是一个古老但仍然非常相关的问题,所以我要补充一点:当你打开一个你以前可能读过或不读过的类文件时,你首先想要的是什么?场?属性?我从经验中意识到,我几乎总是去寻找构造函数,因为最基本的东西是如何构造这个对象.

因此,我已经开始将构造函数放在类文件中,结果在心理上非常积极.将构造函数放在一堆其他东西之后的标准建议感觉不和谐.

C#6中即将出现的主要构造函数功能提供了证据,证明构造函数的自然位置在类的最顶层 - 事实上,即使在开括号之前也指定了主构造函数.

有趣的是,这样的重新排序有多大区别.它让我想起了以前如何对using语句进行排序 - 首先使用System命名空间.Visual Studio的"Organize Usings"命令使用了此命令.现在using只是按字母顺序排序,没有对System命名空间给出特殊处理.结果感觉更简单,更清洁.

  • 在10次中有9次在寻找公共接口,这就是为什么我将所有公共成员放在首位,然后是内部成员,然后是受保护成员,最后是私有成员的原因。 (3认同)
  • 我认为类的初始化/构造是复杂的。字段在运行显式构造函数之前进行了初始化,因此,按照您的论点(实质上是按照使用/创建成员的顺序排列成员),初始化字段将在显式声明的构造函数之前。初始化的静态字段和静态构造函数使其更加有趣。 (2认同)
  • 实际上,人类寻找它们的顺序是文学编程的概念,即代码首先应该是人类可读的。 (2认同)
  • 请注意,从 C# 6 的计划中删除了主要构造函数:/sf/answers/1884106661/ (2认同)

Eli*_*nor 14

我建议使用IDesign的编码标准或Brad Abram网站上列出的编码标准.这是我发现的最好的两个.

布拉德会说......

类成员应按字母顺序排列,并分组为部分(字段,构造函数,属性,事件,方法,私有接口实现,嵌套类型)

  • 这些链接似乎只是导致IDesign主页这些天.现在看来编码标准隐藏在电子邮件下载链接背后#justsaying (3认同)

Way*_*yne 12

我不知道语言或行业标准,但我倾向于按照这个顺序排列,每个部分包含在#region中:

使用语句

命名空间

私人会员

公共财产

构造函数

公共方法

私人方法

  • 如果您的班级足够大,需要区域来帮助查找内容,那么这是一个非常有力的指标,表明您的班级太大了。 (3认同)
  • 任何人都不应该在生产代码中使用区域。如果您的代码中需要区域,那么您的类太大 - 应该提取代码并将其放入其他类中。 (2认同)

blo*_*art 5

来自 StyleCop

私有字段、公共字段、构造函数、属性、公共方法、私有方法

由于 StyleCop 是 MS 构建过程的一部分,您可以将其视为事实上的标准


Mit*_*ers 5

如前所述,C#语言中没有任何内容可以决定布局,我个人使用的是区域,我为普通课程做了类似的事情.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}
Run Code Online (Sandbox Code Playgroud)

无论如何,这对我来说很有意义

  • 以下是(仅供参考)stylecop建议不使用区域(SA1124 DoNotUseRegions) (18认同)
  • [Microsoft本身正在使用区域。](https://github.com/dotnet/corefx/blob/1df4a4866a90f22f861156b8ff496c24103d39cc/src/Common/src/CoreLib/System/Numerics/Vector.cs#L161) (2认同)
  • @zwcloud 当然,在 5538 行的文件中,区域是必要的,但这并不意味着您应该在普通文件中使用区域。 (2认同)

Mic*_*tov 5

通常我会尝试遵循下一个模式:

  • 静态成员(通常具有其他上下文,必须是线程安全的等)
  • 实例成员

每个部分(静态和实例)由以下成员类型组成:

  • 运算符(总是静态的)
  • 字段(在构造函数之前初始化)
  • 构造函数
  • 析构函数(遵循构造函数的传统
  • 特性
  • 方法
  • 事件

然后成员按可见性排序(从较少到较多可见):

  • 私人的
  • 内部的
  • 内部保护
  • 受保护
  • 民众

顺序不是教条:简单的类更容易阅读,但是,更复杂的类需要特定于上下文的分组。


Alu*_*dad 5

我的偏好是按种类排序,然后按如下方式降低可见度

public methods
public events
public properties

protected methods
protected events
protected properties

private methods
private events
private properties
private fields

public delegates
public interfaces
public classes
public structs

protected delegates
protected interfaces
protected classes
protected structs

private delegates
private interfaces
private classes
private structs
Run Code Online (Sandbox Code Playgroud)

我知道这违反了 Style Cop,如果有人能给我一个很好的理由为什么我应该将类型的实现细节放在它的接口之前,我愿意改变。目前,我强烈倾向于将私有成员放在最后。

注意:我不使用公共或受保护的字段。

  • 同意。我真的想知道将私有成员放在首位的概念是否不是必须首先声明变量的 C 时代的延续。我几乎总是想先看到公共接口,而不是类内部。 (3认同)
  • 这实际上很有道理。我敢打赌这是C的遗留物。 (2认同)