クラス内のアイテムの順序:フィールド、プロパティ、コンストラクタ、メソッド


637

クラス構造の観点からのアイテムの順序に関する公式のC#ガイドラインはありますか?

それは行きますか:

  • パブリックフィールド
  • プライベートフィールド
  • プロパティ
  • コンストラクタ
  • メソッド

アイテムの順序について厳格な規則があるかどうか知りたいのですが。私はいたるところにいる。どこでもできるように、特定の基準を守りたいです。

本当の問題は、私のより複雑なプロパティがメソッドのように見えて、コンストラクターの前の最上部で場違いに感じられることです。

ヒント/提案はありますか?


7
実際、実際の質問に答えるには、いいえ、公式のガイドラインはありません。StyleCopは、Microsoftの特定のグループ内で使用するために開発されたガイドラインを実装しています。これは公式のガイドラインではなく、Microsoftのグループ間で統一されていない場合もあります。
John Saunders

2
簡単なトリックの1つは、.net(VSのF12)で複雑なクラスのメタデータを表示することです。あなたはそれが少なくともpublicprotectedメンバーにとってどのように注文されたかを知るようになります。
nawfal 2013年

19
この質問は、公式のガイドラインがあるかどうかを尋ねるため、意見に基づくものではありません。ガイドラインがあるか、ないかです!
SimonMᶜKenzie

2
@nawfal私はこれが古いコメントであることを理解しています。私はあなたが言及したトリックが好きですが、それが表示されない、privateまたはinternalメンバーにならないことは言及する価値があります(私は信じます)。見ての良い方法publicprotectedが、。.NET Frameworkクラスのソースを確認できます。ここではreferencesource.microsoft.com
Adam Plocher

回答:


950

StyleCopルールドキュメントによると、順序は次のとおりです。

クラス、構造体、またはインターフェース内:(SA1201およびSA1203)

  • 定数フィールド
  • 田畑
  • コンストラクタ
  • ファイナライザ(デストラクタ)
  • 代議員
  • イベント
  • 列挙型
  • インターフェース(インターフェース実装
  • プロパティ
  • インデクサー
  • 方法
  • 構造
  • クラス

これらの各グループ内で、アクセス順に並べます:(SA1202)

  • 公衆
  • 内部
  • 保護された内部
  • 保護された
  • 民間

各アクセスグループ内で、静的、非静的の順に並べます(SA1204)。

  • 静的
  • 非静的

フィールドの静的/非静的グループのそれぞれの中で、読み取り専用、非読み取り専用の順に並べます(SA1214およびSA1215)

  • 読み取り専用
  • 非読み取り専用

展開されたリストは130行の長さなので、ここでは展開しません。展開されたメソッド部分は次のとおりです。

  • パブリック静的メソッド
  • 公開メソッド
  • 内部静的メソッド
  • 内部メソッド
  • 保護された内部静的メソッド
  • 保護された内部メソッド
  • 保護された静的メソッド
  • 保護されたメソッド
  • プライベート静的メソッド
  • プライベートメソッド

ドキュメントでは、規定された順序が適切でない場合(たとえば、複数のインターフェースが実装されていて、インターフェースのメソッドとプロパティをグループ化する必要がある場合)、部分クラスを使用して関連するメソッドとプロパティをグループ化していると説明しています。


31
この投稿にご尽力いただき、誠にありがとうございます。私はStyleCopのものを標準にしようとしています(一貫していて、物事を簡単に見つけられるようにするためでも)、これは価値があります。
ケニー・マン

47
個人的に、静的メソッドの順序は面倒です。最初に静的パブリックメソッドの引数が表示されますが、通常はメンバーの後にプライベート静的メソッドが必要です。結局、それらはユーティリティです。
ジョナサンライト

18
部分クラスのヒントが気に入りました
キースサーモンズ2012年

10
部分クラスについてのメモ。コンパイル時にすべてのパーシャルが単一の型にコンパイルされることを考えると、私は常にその追加のオーバーヘッドを作成するための正当な理由を確保しようとします。部分クラスの主な理由は、自動生成のソースコードを拡張するため、または大規模なプロジェクトで作業する場合に、複数の開発者が同じクラスで別々のファイルで作業できるようにするためです。
いいえ、2012

4
@FrançoisWahl部分クラスを1つの型に結合するコンパイラに関連するオーバーヘッドはそれほど大きいですか?
dav_i 2012

38

可視性や項目のタイプ(フィールド、プロパティ、メソッドなど)でグループ化するのではなく、機能でグループ化するのはどうですか?


3
StyleCopの推奨事項を使用して「ソート」する場合、これは一種の機能です。一部のメソッドがパブリックであり、他のメソッドがプライベートであるのには十分な理由があります。コードは本当に読みやすくなっています。クラスの.csファイルを開くと、プライベートメソッドよりも「重要」なパブリックメソッドがすぐにわかります(そのクラスを使用している人にとって)
hfrmobile

75
クラスに非常に多くのメソッド、プロパティなどがあり、セクションごとにグループ化する必要がある場合、それはクラスが多すぎることを示しているのではないでしょうか。
ライアンランディ

10
クラスが小さい場合でも、パブリックメソッドを、このパブリックメソッドによってのみ呼び出される対応するプライベートメソッドとグループ化することは意味がないのではないでしょうか。
Markus Meyer

11
+1パブリックメソッドFoo()がprotected / private InternalFoo()を呼び出す場合、その2番目のメソッドは、ソース内のDoFoo()の真下で、他のプロテクト/プライベートメソッドのどこか下ではない方が適切です。
Anders Forsgren 2013

60
機能によるグループ化はクラスと呼ばれます
MrDosu 2013

26

これは古いですが、それでも非常に関連性の高い質問なので、これを追加します。以前に読んだ、または読んだことがないクラスファイルを開いたときに、最初に何を探しますか?田畑?プロパティ?経験から、ほぼ常にコンストラクタを探していることに気づきました。理解すべき最も基本的なことは、このオブジェクトの構築方法だからです。

したがって、私はコンストラクターをクラスファイルの最初に配置し始め、その結果は心理的に非常にポジティブです。他のものの束の後にコンストラクターを置くという標準的な推奨事項は不快に感じます。

C#6で予定されているプラ​​イマリコンストラクター機能は、コンストラクターの自然な場所がクラスの一番上にあるという証拠を提供します。実際、プライマリコンストラクターは中かっこの前でも指定されます。

このように並べ替えを行うと、どの程度違いが生じるのかはおかしいです。using最初にシステム名前空間を使用して、ステートメントがどのように順序付けされていたかを思い出します。Visual Studioの「Organize Usings」コマンドはこの順序を使用しました。現在using、はアルファベット順に並べられており、System名前空間には特別な扱いはありません。結果は、よりシンプルでクリーンに感じられます。


2
クラスの初期化/構築は、私の意見では複雑です。フィールドは、明示的なコンストラクターが実行される前に初期化されるため、基本的に、メンバーを使用/作成された順に配置するという引数に沿って、初期化されたフィールドは明示的に宣言されたコンストラクターの前になります。初期化された静的フィールドと静的コンストラクターは、さらに興味深いものにします。
デビッドカルプ、2015年

1
実際、それらが人間によって検索される傾向がある順序、つまり、コードは最初に人間が読み取れるべきであるという文学プログラミングの概念。
明るい

1
C#6のプランからプライマリコンストラクターが削除されたことに注意してください:stackoverflow.com/a/26915809/5085211
fuglede

4
10回のうち9回、私はパブリックインターフェイスを探しています。そのため、すべてのパブリックメンバーを最初に配置し、次に内部メンバー、次に保護メンバー、最後にプライベートメンバーを配置します。
マット・デイビス

15

言語や業界標準については知りませんが、各セクションを#regionで囲んで、この順に並べる傾向があります。

ステートメントの使用

名前空間

クラス

プライベートメンバー

パブリックプロパティ

コンストラクタ

パブリックメソッド

プライベートメソッド


これもまさに私がやる方法です。クラスメンバーとプライベートメンバーの間を除いて、パブリック定数や列挙型などがあります。
16年

はい、私はプライベートメソッドの後でパブリックプロパティを保持することを好みます。他の人々は、パブリックプロパティの前にコンストラクターを置くことを好みますが、私の頭の中では、値/コンストラクター/動作の順にすることを好みます。次に、「値」は定数/ privateMembers /プロパティなどに分割されます。いくつかの大きなビューモデルを除いて、通常は領域を使用しません...まあ、WPFビューモデルは一種の特別なものであり、この場合、通常、各パブリックプロパティの直前にバッキングプライベートフィールドを配置します。この場合、プライベートフィールドのセットに加えて公共のメンバーは同じユニットである
zameb

15

IDesignのコーディング標準、またはBrad AbramのWebサイトに記載されているコーディング標準を使用することをお勧めします。それらは私が見つけた最高の2つです。

ブラッドは言うだろう...

クラスメンバーはアルファベット順に並べられ、セクション(フィールド、コンストラクター、プロパティ、イベント、メソッド、プライベートインターフェイス実装、入れ子型)にグループ化されます。


3
このリンクは、最近のIDesignホームページにリンクしているようです。最近、コーディング標準が電子メールで送信されるダウンロードリンクの背後に隠れているようです。#justsaying
Liam

ガイドラインには根拠が必要です。その理由は次のとおりです。1。理解するため、2。境界線、微妙、あいまい、予期しない、または矛盾するケースに判断を適用できるようにする、3。条件が変化し、一部のガイドラインが適用されなくなったときに調整できるようにする。
Pablo H

6

前述のとおり、C#言語にはレイアウトを指示するものは何もありません。私は個人的にリージョンを使用しており、平均的なクラスに対してはこのようなことをしています。

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

とにかく私には理にかなっています


19
ここで(情報のみ)、stylecopは領域の使用を推奨しない(SA1124 DoNotUseRegions)
Gerwald


1
@zwcloud確かに、5538行のファイルではリージョンが必要ですが、それは通常のファイルでリージョンを使用する必要があるという意味ではありません。
Ghost4Man 2018年

1
@Gerwald:StyleCopはStyleCopを使用する人のためだけのものだと思います。これは多くの標準の1つです
zameb 2018

1
@zameb:StyleCopルールはC#の最も一般的なコーディングガイドラインの1つです。どの言語でコーディングするときも、私は常に最も一般的なコーディングガイドラインのセットを見つけて、それに従うようにしています。
ガーヴァルト2018

5

StyleCopから

プライベートフィールド、パブリックフィールド、コンストラクター、プロパティ、パブリックメソッド、プライベートメソッド

StyleCopはMSビルドプロセスの一部であるため、事実上の標準と見なすことができます


面白い。StyleCopを定期的に使用していますか?
mmcdole 2008

1つのプロジェクトでは、いくつかのMS契約作業に何度も使用されるためです。それは非常に迷惑な
にやにや

1
StyleCopを長期間使用し、その推奨事項を使用すると、コードが本当に読みやすくなります。クラスの.csファイルを開くと、プライベートメソッドよりも「重要」なパブリックメソッドがすぐにわかります。パブリックは、クラスの「インターフェース」であり、クラスが提供するものとテストできるものです(TDDを優先し、テストファースト)
hfrmobile

1
StyleCop公共の場によると、民間分野の前に行くべきstylecop.com/docs/SA1202.html
マイケルFreidgeim

1
「StyleCopはMSビルドプロセスの一部です」とはどういう意味ですか?マイクロソフトはすべてのコードにStyleCopを使用していますか?
Rico Suter、2014

5

通常、私は次のパターンに従うようにしています:

  • 静的メンバー(通常、他のコンテキストがあり、スレッドセーフでなければなりません)
  • インスタンスメンバー

各部分(静的およびインスタンス)は、次のメンバータイプで構成されています。

  • 演算子(常に静的)
  • フィールド(コンストラクタの前に初期化)
  • コンストラクタ
  • デストラクタ(コンストラクタをフォローする伝統です
  • プロパティ
  • メソッド
  • イベント

次に、メンバーは可視性で並べ替えられます(表示が少ないものから表示されやすいものへ)。

  • 民間
  • 内部
  • 内部保護
  • 保護された
  • 公衆

順序はドグマではありません。単純なクラスの方が読みやすいですが、より複雑なクラスにはコンテキスト固有のグループ化が必要です。


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

これはStyle Copに違反していることを知っています。誰かが、インターフェースの前に型の実装の詳細を配置する必要があるという正当な理由を私に与えることができるなら、私は変更したいです。現在、私はプライベートメンバーを最後に置くことを強く望んでいます。

注:パブリックフィールドや保護フィールドは使用しません。


3
同意した。プライベートメンバーを最初に置くという考えは、変数を最初に宣言する必要があったCの時代からの引き継ぎではないのか、私は本当に不思議に思います。ほとんどの場合、クラスの内部ではなく、最初にパブリックインターフェイスを確認したいと考えています。
マット・デイビス

1
それは実際には非常に理にかなっています。私はそれがCからホールドオーバで賭け
Aluanハダッド

最大の落とし穴のいくつかは、プロパティIMOです。あなたが気づいていなかったゲッター/セッターにロジックがある場合、それはメソッドの副作用よりもはるかに噛みやすくなります(当然のことながら、メソッドがそこにあると期待します)したがって、私は上部のフィールドと一緒にプロパティを優先します、だから私が初めてクラスを見ているとき、私は得点が上にあるのを見る。メソッドを読んだときと同じように、通常はとにかく
Ryan The Leach


3

これについて提案された唯一のコーディングガイドラインは、クラス定義の先頭にフィールドを配置することです。

次にコンストラクタを置く傾向があります。

私の一般的なコメントは、ファイルごとに1つのクラスに固執する必要があり、クラスがプロパティとメソッドの編成が大きな問題であるほど大きい場合、クラスはどのくらいの大きさであり、とにかくそれをリファクタリングする必要があるかです。それは複数の懸念を表していますか?


3
そして、あなたが地域を必要としたら...あなたは負けました。
Hamish Smith

3

私は、プライベートフィールドをコンストラクタと共に一番上に配置し、その後にパブリックインターフェイスビットを配置し、次にプライベートインターフェイスビットを配置することをお勧めします。

また、クラス定義が項目の順序が重要になるほど長い場合、それはおそらく、クラスがかさばりすぎて複雑であることを示すコードのにおいであり、リファクタリングする必要があります。


3

私はそれを可能な限り単純にします(少なくとも私にとっては)

列挙
宣言
コンストラクター
オーバーライド
メソッド
プロパティ
イベントハンドラー


2

確かに、それを強制する言語には何もありません。プロパティ、メソッドなどに関係なく、可視性(パブリック、保護、プライベート)でグループ化し、#regionsを使用して、関連するものを機能的にグループ化する傾向があります。クライアントが最初に知る必要があるので、構築メソッド(実際のctorでも静的ファクトリー関数でも)は通常、一番上にあります。


私はリージョンを使用して、可視性によっても分離します。Regionerateコードレイアウトを使用すると、正直に保つことができます。 rauchy.net/regionerate
忘れられたセミコロン

#regionsの使用に問題はありませんが、リージョンに入れたくなったらすぐに、クラスを分割することを検討するように促されます。
mikecamimo 2018

2

これは古いのですが、私の注文は次のとおりです。

パブリック、保護、プライベート、内部、抽象の順に

  • 定数
  • 静的変数
  • 田畑
  • イベント
  • コンストラクタ
  • 方法
  • プロパティ
  • 代議員

私はまた、このようなプロパティを(略式のアプローチの代わりに)書き出すのが好きです

// Some where in the fields section
private int someVariable;

// I also refrain from
// declaring variables outside of the constructor

// and some where in the properties section I do
public int SomeVariable
{
    get { return someVariable; }
    set { someVariable = value; }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.