.NETのファイルルールごとに1つのクラス?[閉まっている]


185

私はこの規則に従いますが、同僚の何人かはそれに同意せず、クラスが小さい場合、他のクラスと同じファイルに残すことができると主張しています。

私がよく耳にするもう1つの主張は、「Microsoftでもこれを行わないので、なぜ私たちがすべきなのか」というものです。

これについての一般的な合意は何ですか?これを避けるべきケースはありますか?



回答:


176

また、ファイルごとに1つのクラスを使用すると、ファイルの差分を見ずに、各チェックインの変更内容をより適切に把握できます。


4
同じファイル内のクラスが多いほど、1回の操作で関連するクラス間の相違が強化されます。
Luca

3
適切な差分ビューアを使用すると、1つのコミットのすべての差分を表示できます。
Dykam

44
この特定の答えが元の投稿の質問に対する答えであるかどうかは、完全にはわかりません。確かにそれは1つのクラスをファイルに保持する理由を提供します(ただし、LucaとDykamは良い点を示しています)が、一般的なコンセンサスを反映したり、回避すべきケースを提供したりするものではありません。
ロバート・デイビス

3
ベストプラクティスが存在しない場合、ベストプラクティスを信じれば、それらは特定のコンテキストにのみ適用されます。他の応答が指摘しているように、このルールが実際には保守性の低いコードを作成する場合があります。ツールが良くなるにつれ、このルールはプロジェクト内のクラスとタイプを見つけるのがはるかに簡単になるため、実際にはあまり関係がなくなります。
2011年

262

人々が絶対的に考えて、これを絶対に誰かが愚かで正しいか間違っているかを理解する必要があるかのように、このような主観的で気の利いた何かで決してやるべきではないと言うとき、私はそれを嫌います。結論:理にかなっている場合、ファイルごとに複数のクラスがあることはまったく問題ありません。理にかなっていると私は次のようなことを意味します:

  1. コードを消化し、維持することをより簡単にします
  2. ソリューションの煩わしさを減らし(無数の不要なファイルをスクロールする)、速度を低下させます
  3. 開発チームは、ローカルのコーディングプラクティスとしてそれで大丈夫です

ファイルごとに複数のクラスが必要な理由の本当に良い例:

たとえば、数十のカスタム例外クラスがあり、それぞれが4ライナーであるとします。それぞれに個別のファイルを作成したり、例外をグループ化したり、グループごとにファイルを作成したりできます。私にとって最も合理的/実用的なアプローチは、それらをグループ化し、いくつかのファイルを用意することです。これは、時間/コーディングの点でより効率的であるためです(右クリック->クラスの追加、名前の変更、50回は不要です)。 、ソリューションが雑然としてなくなり、パフォーマンスが向上します。


92
+1,000。ベストプラクティスの根拠を理解し、違反する前に2度考えることは素晴らしいことです。奴隷の遵守は悪です。
dsimcha

19
数十のカスタム例外クラス?それが問題の本当の原因ではありませんか?私はここで一律にこだわるつもりはありません。ほとんどの場合、人々がクラスを1つのファイルに結合することを望んでいると思います。それは、不必要に多くの型を作成しているためです。(とはいえ、実際には、数十のカスタム例外クラスが理にかなっている場合もあります)。多数の小さい、何もしないクラスは、通常、より大きな問題の兆候です。
ジェフ

16
大部分はあなたに同意します。ただし、例外は特別な場合です。適切に設計されたシステムでは、正当なエラーが発生するすべてのケースに対処するために適切な例外処理が必要であるため、私が読んだベストプラクティスの記事のほとんどは、特定の例外を作成する必要性を強調しています(場合によっては、大規模なプロジェクトのすべてのビジネスルールをカバーします)。これにより、適切な例外処理ではないsystem.exceptionをキャッチすることがなくなります。
James

6
正当な理由がない限り、いくつかのガイドラインを怠ってはならないことに同意しますが、ファイルに複数のクラスを含める必要があるという事実には同意しません。私にとって、ファイルはクラスにちなんで名付けられるべきであり、複数を含んではいけません。一部の言語(Javaは1つです)は、クラスがファイル内にあり、ファイル名がクラス名と一致することを実際に強制していることに注意しています。私にとっては、それが簡単に新しい仲間が、私はファイルごとに1つのクラスが行うには正しいことだと信じている理由ので、ナビゲートすることを可能にする
krystan名誉

3
ファイルごとに1つのクラスを保持し、ファイル名とクラス名を同期させることは、変数に名前を付けるのと同じように規則です。Visual Studioは、このアプローチに対して非常によく調整されています。ソース管理システム、およびプロジェクトの途中で追加される開発者にとっては簡単です。クラス名と一致するファイル名を直感的に検索します。
Oybek 2013年

75
static bool GeneralRuleShouldBeFollowed(IGeneralRule rule, IUseCase useCase)
{
    return (rule.Overhead(useCase) 
            < My.PersonalThresholds.ConformismVsPracticality);
}

4
.NETにそのようなルールはありますか?私はまた、ステートメントの結果を返しました。:O
Joan Venge

50

クラスが密結合で、少なくとも1つが非常に小さい場合、ファイル内の複数のクラスをグループ化することがあります。

一般的な「ベストプラクティス」は、クラスごとに1つのファイルを用意することです。


7
それらが結合されていることを認識したら、なぜそれらを分離しないのですか?
マット

39
@The Matt:オーバーエンジニアリングの回避と呼ばれています。密接に結合されたクラスがいくつかあり、それらをデカップリングすると、クラスが提供する実際的な柔軟性の量に比べて多くの複雑さが追加されますが、ポイントは何ですか?
dsimcha

9
この1つのクラスでのみ使用される基本的に「データ」クラスが好きな場合があるので、通常はデータクラスをユーザーと同じファイルに配置します。新しいファイルを作成するのは無駄です。
Earlz 2010年

3
@The Matt:結合が許容できると主張するヘルパークラスが時々あります。これらは、別のクラスの一部の複雑さを軽減しますが、そのクラスの非常に特定の目的を容易にします。
ジョーダンパーマー、

6
@TheMatt:これを分離する:msdn.microsoft.com/en-us/library/… モジュール間のカップリングは悪いですが、論理機能内のクラス間のコラボレーションは避けられません。
Ben Voigt

25

架空の議論を超えて、代わりにVisual Studio IDEを備えたWindows .NETと成長しているソフトウェアプロジェクトに焦点を当てるだけで、このコンテキストでは、ファイルごとに1つのクラスを持つことが理にかなっています。


一般に、視覚的な参照では、ファイルごとに1つのクラスに勝るものはありません。本当に。

Microsoftが同じことをするかしないかはわかりませんが、1つのクラスを複数のファイルに分割するpartialキーワードを作成しました(これはさらに深刻です)。多くの場合、自動生成されたデザイナーコードをカスタムコードから同じクラスに分割するために使用されます(ただし、異なる開発者が異なるファイルを使用して同時にクラスで作業できるようにするために使用されることもあります)。したがって、Microsoftは複数のファイルの利点を認識しており、誰もが.NETで確実に複数のファイル編成の考えを持っています。

ネストされたクラスの場合、1つのファイル、または少なくともそれらのクラスの最初の部分を使用する以外に選択肢はありません。この場合、1つのファイルが必要であり、問​​題ありません。

class BicycleWheel {
    class WheelSpoke {
    }
}

そうでない場合、なぜ複数のクラスを1つのファイルに保持するのでしょうか。「小さいので」または互いに関連付けられ ているという議論、結局のところクラスが他のクラスに関連付けられるため、多くの水を保持しません最終的には、特にソフトウェアが成長し続けるので、オブジェクトの使用状況に基づいてオブジェクトのファイル内編成を簡単に推測することはできません

さらに、名前空間にフォルダーを使用する場合、クラスのファイル名が衝突することはありません。Visual Studioのような開発環境ではない場合(たとえば、メモ帳などのクイック/ライトでクラスをすばやく編集したい場合)、ファイルシステム上のファイル名でクラス検索すると便利です。

非常に多くの理由があります...


ありがとう、「少なくとも最初の部分」とはどういう意味ですか?ネストされたクラスを分離することもできますか?
Joan Venge

1
それはpartial私が言及したキーワードへの間接的な参照です。
ジョンK

1
レコードの場合、ネストされたクラスはpartial msdn.microsoft.com/en-us/library/wa80x488(VS.80).aspx にすることができます。私はこれを好奇心から調べました。
John K

これは、デフォルトのビューが物理的(ファイル)ではなく論理的(名前空間/クラス)であることを示すためにのみ使用されます。
デビッドシュミット

@DavidSchmittは、Visual Studioのクラスビューです。
ザック

14

ほとんどの場合、ファイルごとに1つのクラスのルールに従います。私が定期的に行う唯一の例外は、特定のクラスに密結合されている列挙型の定義です。その1つのケースでは、列挙型の定義をそのクラスのファイルに頻繁に含めます。


12

私も、1つのファイルに1つのタイプを含める必要があると考えています。

このルールには1つの例外があります。それは、次のような一般的な引数だけが異なる2つのクラスがあることです。

RelayCommand     

そして

RelayCommand<T>

この場合、StyleCopを幸せにするための回避策を知っていますか?
George Polevoy

同意しない、汎用クラスには別の規約、Foo 1.cs for Foo <T> `とFoo 2.cs for Foo <T、T1>`があります。
Oybek 2013年

@Oybek:Foo <T>、Foo <U>、Foo <U、T>がある場合はどうなりますか?それで?
AndreiRînea2013年

@AndreiRinea持ってすることは不可能ですFoo<T>し、Foo<U>同じ名前空間内。しかし、名前空間が異なる場合、それらは通常異なるフォルダーにあります。したがってためFoo<T>、およびFoo<U>それがFooのであるべきで1.cs and for はFoo <U、T> `Foo`2.cs。しかし、それでもファイルごとに1つのクラスです。
Oybek 2013年

情報ありがとうございます!:)
AndreiRînea2013年

7

本当に、これは結局個人の好みに帰着します。誰もが「ファイルごとに1つのクラス」と言うでしょうが、私たちは皆、特定の状況でそれを回避する理由があります。私は以前、約300の列挙型を持つ大規模なプロジェクトを持っていました。いくつかの列挙型がトライステートのみだった場合、クラスごとに1つずつ、300個の個別のファイルを作成することはできません。

また、特定のクラスがすべて、それらが何であるかにちなんで名付けられたファイルに含まれていない場合、特定のクラスを見つけることができない人にとって、ソリューション全体で検索を使用しない理由はありますか?[検索]を使用すると、ソリューションエクスプローラーをスクロールする貴重な時間を節約できます。


Re:検索-型の定義を探しているとき、それがどこで使用されているのか知りたくありません。その上、findは、おそらく(ネームスペースで)すでに分割されているアルファベット順にソートされたファイルのリストをスクロールするよりもかなり時間がかかります。
Jeff Sternal

1
名前空間で分割したものを使用しているとおっしゃっていましたね。残念ながら、私たち全員が、管理できたプロジェクトを常に処理できるほど幸運なわけではありません。
Jason M

6

コンテンツがどれほど軽量であっても、ファイルごとに1つのクラス/インターフェイスなどが不可欠だと思います。

Visual Studioで大きなソリューションに取り組んでいる場合、ファイルを表示できるようにしたいので、内部を調べて表示する必要はありません。ReSharperのようなナビゲーションツールでも、1対1のマッピングが必要です。

コンテンツがほとんどまたはまったくないソースファイルがたくさんある場合(クラスを拡張しているのにクラスに何も追加していない可能性があります)、おそらく設計を再考する必要があります。



5

私は通常、ファイルごとに1つのクラスを持っていますが、通常は自分の裁量を使用して、ファイルに関連するクラスが含まれているかどうかを確認する必要があります。この場合、ユーザーは複数のファイルではなく、1つのファイルのみを含める必要があります。

したがって、ポイントは次のとおりです。裁量を使用する必要があります!!!


1
真の知恵、プログラミングのルールは難しく、速くありません。
ChaosPandion 2010年

4

大規模なソリューションでは、ファイルごとに1つのクラスがあり、ファイルにはクラスと同じ名前が付けられることが非常に価値があると思います。作業に必要なコードを簡単に見つけることができます。


ReSharperのようなツールでは、この議論はあまり価値がありません。CTRL + Tを押して、探しているタイプの名前の入力を開始します。
Mark

3
はい。ただし、アプリケーション構造をサードパーティのツールに依存させたいですか?
magnus 2010年

1
@magnusこれはそれをしない理由ではないと言っていませんでしたが、誰かがそれをするための議論のあまり説得力がありません。
Mark

4

C#のStyleCopツールには、1つの名前空間に1つだけのトップレベルクラス(およびその名前空間の任意の数のインターフェイス、デリゲート、列挙型)を必要とする標準ルールがあります。

2番目以降のクラスが最初のクラスによってのみ使用される2つ以上のクラスの場合、それらは内部クラスである可能性があり、内部クラスである必要があります。


3
「1つの名前空間にあるトップレベルクラスは1つだけ」とは、1つのnamespaceブロックを意味しますよね?
Daniel Pryden、2010年

1
言及されているルールはSA1403です。AC#ドキュメントには単一の名前空間のみを含めることができます。SA1402:すべてのクラスが部分的で同じタイプでない限り、AC#ドキュメントにはルートレベルで単一のクラスのみが含まれます。
Steve Gilham、2010年

4

時々ファイルごとに1つのクラスです ...

複数のクラスをstricly関連している場合、同じソースファイル内の複数のクラスは、私見、あるBETTER各クラスに短いソース・ファイルを専用に比べ。ソースはより読みやすくコンパクトです(#regionを使用すると、同じソースを以前よりも構造化できます)。

時にはそれがだとも考えてみましょうNECESSARY(使用して異なるファイル間で同じクラスを広めるために、部分的に 20000+ラインソース・ファイルを持つことは、私が用意して(これは別の問題です)RAMと便利でもないので、)。


もちろん、コードの行数が非常に多いクラスは避けてください。1000以上でも大きくなりすぎると思います。また、これがレガシーコードで常に可能であるとは限らないことも理解しています。
Peter

ソースコードを生成しようとすると(私の場合は、その仕様からOpenGLのC#バインディングを生成し、何千ものエントリポイントがあります)、大量のデータ用の小さなクラスを考えるのは難しい...
Luca

3

小さなクラスを大きなクラスと一緒に残すこともありますが、それらがオブジェクトとコレクションクラスまたはファクトリーのように非常に密接に関連している場合のみです。

ただし、これには1つの問題があります。最終的に、小さなクラスは、それが独自のファイルにあるべきポイントまで大きくなります。それを新しいファイルに移動すると、変更履歴に簡単にアクセスできなくなります。

すなわち。

  • 月曜日に、ファイルy.cssのクラスxとyに変更を加えます
  • 火曜日に、クラスxを独自のファイルx.cssに分離しました。
  • 水曜日に上司が月曜日にクラスxで何を変更したかを確認したいので、彼はx.cssの履歴を確認します。火曜日が変更される前にx.cssだけが履歴を表示しません。

1
「小さなクラス」が、クラスのイベントの受信者に情報を渡すことを目的としたEventArgsの派生物のような場合はどうなりますか?そのようなものを別のファイルに移動することで、コードはよりクリーンになり、保守が容易になりますか?間違いなく、そのようなものはネストされたパブリッククラスであるべきですが、それらも不快に思われます。変更履歴については、クラスが変更ログのどこからともなく現れたのではないでしょうか。また、それがどこから来たのかをコードノートにコメントすべきではありませんか?
スーパーキャット2011年

私はそれをクラスとしてvery tightly related分類し、それが画面のスペースを少ししか占有せず、他のクラスによって同じ目的で使用されない場合は、そのままにしておきます。
gingerbreadboy

3

これは本当に問題なのでしょうか?:)
enumのように、本当に小さなクラスは他のクラスと一緒に置くことができます。従うべきルールが1つあります。共通するものがあるクラスのみをまとめます。

余談ですが、私のプロジェクトの1つに、内部に150のクラスがあるファイルがあります。ファイルには10000行のコードがあります。しかし、それは自動生成されるので、完全に許容できます:)


1
私は同じファイルに120のクラスと50万行の750のサブクラスを持っていますが、それも自動生成されます。問題は、それをクリックした場合、すべてが停止するため再起動する必要があります。
Behrooz、2010

3

1 つのファイルに複数の関連クラスを配置する理由の1つは、APIを使用する貧しい野郎がインポート宣言のボイラープレートを入力するのに半日費やす必要がなく、コードを保守する必要のある貧しい野郎が半分費やす必要がないためです。インポート宣言のボイラープレートをスクロールする1日。私の経験則では、ほとんどの場合、一度に1つだけではなく、同時に大きなサブセットを使用する場合、複数のクラスが同じファイルに属します。


1
「輸入申告定型文」とはどういう意味ですか?「ステートメントを使う」?しかし、クラスは同じ名前空間にあるのではないでしょうか?
Joan Venge

3
@ジョアン:本当にシンプルなものを実現するために、15の異なる関連モジュールをインポートする必要があることを意味します。多分それは特にC#に適用されません。C#は本当にわかりませんが、他の言語ではかなり厄介な問題です。
dsimcha

ええありがとう、それで私は混乱しました。
Joan Venge 2010年

2

私はこれを行いますが、クラスが親子関係で関連付けられており、子クラスが親によってのみ使用されている場合のみです。


ありがとうございます。でも、別のファイルに分けてみませんか?ちょっと興味があるんだけど。
Joan Venge

@henchmanは、特に子オブジェクトが非常に小さい場合に、私よりもはるかに雄弁に語っています。通常、子クラスはプロパティであり、ロジックはほんの少ししかありません
CResults

2

私は通常、ファイルごとに1つのクラスを使います。ただし、プロジェクト全体で使用される類似の構成要素のグループについては例外を設けます。例えば:

  • EventArgsサブクラスを含むEventArgs.cs 。これらは通常、それぞれ5行から10行のコードですが、通常、いくつかの異なるクラスで使用されます。または、EventArgsイベントを宣言するクラスと同じファイルにクラスを配置することもできます。
  • プロジェクト全体で使用されるデリゲートを含むDelegates.cs。これらは通常、それぞれ1行しかないためです。繰り返しになりますが、それらを公開/消費するクラスと同じファイルにそれらを置くことです。
  • enumプロジェクト全体で使用されるを含むEnums.cs 。(enum1つのクラスでのみ使用されるものが存在する場合、通常はprivateそのクラスに到達します。)

2

ファイルとクラスの名前が同じであるファイルごとに1つのクラスに対する別の投票。私にとって、それは長期的な保守性に役立ちます。プロジェクトやファイルを開かなくても、リポジトリを簡単に確認して、ソリューションの一部であるクラスを確認できます。


2

私はそれを99%の確率でフォローしています。標準に従うことは良いことですが、柔軟性があることも信じています。時々、物事を分解するのは時間の愚かな無駄のように思えます。その時は、自分を乗り越えてコードを書くだけです。


2

これまでの応答は、ルールに対する人々の例外を中心に展開しているように見えるので、これは私のものです。それ以外の場合は、常に別のファイルにあります。ほとんどの場合、知っています。そうでない場合を除きます。


2

私はめったにこれをしません。たとえば、クラスに密接に関連しているが、それ自体では分離するには小さすぎる列挙または構造体がある場合。

または、そのメインクラスの拡張メソッドを含む別のクラス。


1

One case could be:あなたのクラスは、共同で形成するときmodule / unitのようないくつかの主要なクラス働くことがhelper classes、他の賢明なノーを

ASP.NET MVC 2.0プロジェクトのソースコードをご覧ください。このルールに厳密に従います


1

小さいクラスを作成し、クラスが本来の機能だけを実行するようにするというアイデアが気に入っています。単一の問題の解決に貢献している複数のクラスがある場合、それらを同じファイルにまとめても害はありません。

MSのプラクティスはベストプラクティスではないので、私はフォローしません!


1

ファイルルールごとに1つのクラスを使用して開発すると、その特定のクラスが使用しているものを簡単に確認できることは、他の人が言及したことはありません。

たとえば、2つのクラスがあり、一方のクラスがLinqを使用し、もう一方のクラスがLinqを使用しない場合があります。

これらのクラスが同じファイル内にある場合、どのクラスが何を使用しているかをコードで調べないと、判別できません。ファイルごとに1つのクラスである場合は、ファイルの先頭を見て、そのクラスで使用されているものを正確に確認するだけです。新しいライブラリなどに移行する場合に役立ちます。


0

これまでに投稿された回答で言及されていないファイルごとに1クラスのもう1つの理由は、ファイルごとに1クラスを使用すると、コードレビュー中にPRの影響を理解しやすくなるためです。また、マージの競合も減少します。

誰かがフィードバックのためにPRを投稿すると、変更されたファイルのリストを見ることができ、私が取り組んでいるものとの重複をすぐに確認できます。オーバーラップによっては、自分のコードに深く影響を与えたり、自分の変更に影響を与えたりすることはないと確信しているので、OKにしたいと思うかもしれません。

2人がマルチクラスファイルで作業していて、両方が依存関係を追加している場合using、上部のブロックでマージの競合が発生する可能性が高くなります。クラスをファイルに分離すると、依存関係が分離されるため、各クラスが使用しているものを確認でき、このような競合が発生しなくなります。

このルールには例外があります(インターフェース+実装、列挙型など)が、通常、ジュニア開発者がすべての種類の無関係なクラスを同じファイルにバンドルできるようにする反対よりも良い出発点です。

ファイルごとに1クラスは、解釈の対象とならない明確で明確なルールです。


ファイル内の関連クラスは、個人的な好みと解釈の影響を受け(使用できるかどうかに関する他のすべての回答からわかるように)、したがって、不適切なルールです。


-1

個人と個人の例外はあるものの、クラスとファイル間の1-1マッピングが大多数の意見であるという私の一般的な印象はありますが、前後は非常に興味深いもので、一見決定的ではありません。

あなたの答えがあなたが次のどちらであるかによって異なるかどうか、私は興味があります。(1)Windowsフォームアプリ、Webアプリ、ライブラリ、またはその他の開発 または(2)Visual Studioを使用するかどうか。VSを使用する場合、他のスレッドのコンセンサスはVSソリューション/プロジェクトをディレクトリ/ファイルの名前と構造にミラーリングする必要があるため、ファイルルールごとに1つのクラスはVSプロジェクトごとに1つのクラスを意味するように見えます。確かに、私の印象は、コンセンサスがプロジェクト名=アセンブリ名=(ネストされた)名前空間名を持つことであり、それらはすべてディレクトリ/ファイルの名前と構造に反映されます。これらが適切なガイドライン(またはルール)である場合、これらの外見上は直交する組織化メカニズムはすべて同期されます。


-1

はい、読みやすくするために、クラスごとに1つのファイルが必要です!。ちょうどプロジェクトに飛び込んだ。1つのファイルに多くのクラスが表示されます。新しい人がそれを理解するのをとても難しくするだけです。保守性について考えるべきではありませんか?ソフトウェアを開発するとき?多くの場合、開発は他の開発者によって継続されます。ものを配置するための名前空間があります。それを行うためにファイルは必要ありません!。


-5

はい、ファイルごとに1つのコード項目です。

それ以外はすべて不正行為であり、率直に言って、RADの被害の兆候です。

適切なソフトウェア開発(IoC、デザインパターン、DDD、TDDなど...)を開始し、「omgでこれを実行できるようになると、どうすればよいかわからないが、支払いを受ける」というプレイグラウンドを離れるとすぐに、このルールは本当に、本当に、重要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.