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

在类结构方面,是否有官方的C#指南来指导项目的顺序?

它去:

  • 公共领域
  • 私有领域
  • 属性
  • 构造器
  • 方法

我很好奇是否有关于物品顺序的硬性规定?我有点到处都是。我想坚持一个特定的标准,这样我就可以在任何地方做到这一点。

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

任何提示/建议?

313005 次浏览

语言中当然没有任何内容可以强制执行它。我倾向于按照可见性(公共,然后受保护,然后私有)对事物进行分组,并使用#区域在功能上对相关的事物进行分组,不管它是属性、方法还是其他什么。构造方法(无论是实际的ctor还是静态工厂函数)通常都在顶部,因为它们是客户需要知道的第一件事。

我看到的唯一建议的编码准则是将字段放在类定义的顶部。

我倾向于把构造函数放在下一个。

我的一般意见是,您应该坚持每个文件一个类,如果类足够大,以至于属性与方法的组织是一个大问题,那么类有多大,您应该重构它吗?它是否代表多个问题?

您可能会找到最接近的是Brad Abrams的“设计指南、托管代码和. NET Framework”(http://blogs.msdn.com/brada/articles/361363.aspx

这里概述了许多标准。我认为相关部分是2.8。

我不知道语言或行业标准,但我倾向于按以下顺序排列,每个部分都包装在#区域中:

使用语句

命名空间

私人成员

公共财产

构造器

公共方法

私有方法

我建议使用IDesignBrad Abram的网站中列出的编码标准。这是我找到的最好的两个。

Brad会说…

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

与其按可见性或项目类型(字段、属性、方法等)分组,不如按功能分组?

来自StyleCop

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

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

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

public class myClass{#region Private Members
#endregion#region Public Properties
#endregion
#region Constructors
#endregion#region Public Methods
#endregion}

这对我来说是有意义的

我更喜欢将私有字段与构造函数一起放在顶部,然后将公共接口位放在之后,然后是私有接口位。

此外,如果您的类定义足够长,以至于项目的排序很重要,那么这可能是一个代码气味,表明您的类过于庞大和复杂,您应该重构。

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

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

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

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

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

  • 私人
  • 内部
  • 内部保护
  • 保护
  • 公共

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

我尽可能保持简单(至少对我来说)

枚举
声明
构造函数
覆盖
方法
属性
事件处理程序

根据StyleCop规则文档排序如下。

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

  • 常数域
  • 字段
  • 构造器
  • 终结器(析构器)
  • 代表
  • 活动
  • 枚举
  • 接口(接口实现
  • 属性
  • 索引器
  • 方法
  • 结构

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

  • 公共
  • 内部
  • 保护内部
  • 保护
  • 私人

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

  • 静态
  • 非静态

在每个静态/非静态字段组中,按只读顺序,然后按非只读顺序:(SA1214和SA1215)

  • 只读
  • 非只读

展开的列表有130行长,所以我就不展开了。展开的方法部分是:

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

留档指出,如果规定的顺序不合适——比如说,正在实现多个接口,接口方法和属性应该组合在一起——然后使用一个部分类将相关的方法和属性组合在一起。

这是一个古老但仍然非常相关的问题,所以我要补充一下:当你打开一个你可能以前读过或可能没有读过的类文件时,你首先要找的是什么?字段?属性?我从经验中意识到,我几乎总是在寻找构造函数,因为要理解的最基本的事情是这个对象是如何构造的。

因此,我开始将构造函数放在类文件的第一位,结果在心理上非常积极。将构造函数放在一堆其他事情之后的标准建议感觉不和谐。

C#6中即将到来的主构造函数特性提供了证据,证明构造函数的自然位置是在类的最顶部-事实上,主构造函数甚至在开大括号之前就已经指定了。

有趣的是,像这样的重新排序会产生多大的不同。它让我想起了using语句过去是如何排序的——首先是系统命名空间。Visual Studio的“组织使用”命令使用了这个顺序。现在using只是按字母顺序排序,没有对系统命名空间进行特殊处理。结果感觉更简单、更干净。

我的偏好是按种类订购,然后降低可见度,如下所示

public methodspublic eventspublic properties
protected methodsprotected eventsprotected properties
private methodsprivate eventsprivate propertiesprivate fields
public delegatespublic interfacespublic classespublic structs
protected delegatesprotected interfacesprotected classesprotected structs
private delegatesprivate interfacesprivate classesprivate structs

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

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

我知道这是旧的,但我的命令如下:

按照公共、受保护、私有、内部、抽象的顺序

  • 常量
  • 静态变量
  • 字段
  • 活动
  • 构造函数
  • 方法
  • 属性
  • 代表

我也喜欢写出这样的属性(而不是速记方法)

// Some where in the fields sectionprivate int someVariable;
// I also refrain from// declaring variables outside of the constructor
// and some where in the properties section I dopublic int SomeVariable{get { return someVariable; }set { someVariable = value; }}

我重新调整了已接受的答案,至于我认为更好的布局:

在类、结构或接口中:

  • 常数域
  • 只读字段
  • 字段
  • 活动
  • 属性
  • 索引器
  • 构造器
  • 终结器(析构器)
  • 接口(接口实现)
  • 方法
  • 结构
  • 枚举
  • 代表

在每个组中,按访问顺序排列:

  • 公共
  • 内部
  • 保护内部
  • 保护
  • 私人

在每个访问组中,按静态顺序,然后按非静态顺序:

  • 静态
  • 非静态

我还觉得嵌套类型应该保持在最低限度。我经常看到人们有嵌套类、枚举、委托,它们最好是一个单独的实例。嵌套类型几乎没有任何好处。也把它们放在单独的文件中。一个有5个类的文件对我来说感觉很混乱。