C# での内部クラスの使用と構造に関するベスト プラクティスは何ですか。
たとえば、非常に大きな基本クラスと 2 つの大きな内部クラスがある場合、それらを別々の (部分クラス) コードファイルに分割するか、1 つの非常に大きく扱いにくいコードファイルのままにしておく必要がありますか?
また、パブリック継承された内部クラスを持つ抽象クラスを持つことは悪い習慣ですか?
C# での内部クラスの使用と構造に関するベスト プラクティスは何ですか。
たとえば、非常に大きな基本クラスと 2 つの大きな内部クラスがある場合、それらを別々の (部分クラス) コードファイルに分割するか、1 つの非常に大きく扱いにくいコードファイルのままにしておく必要がありますか?
また、パブリック継承された内部クラスを持つ抽象クラスを持つことは悪い習慣ですか?
通常、次の 2 つの目的のいずれかのために内部クラスを予約します。
親クラスが 1 つ以上の抽象メソッドを持つ抽象基本実装であり、各サブクラスが特定の実装を提供する実装である、親クラスから派生するパブリック クラス。フレームワークの設計とガイドラインを読んだ後、これは「回避」とマークされていることがわかりましたが、列挙型に似たシナリオで使用していますが、おそらく悪い印象も与えています
内部クラスはプライベートであり、ビジネス ロジックの単位であるか、他のクラスによって消費または使用されると根本的に壊れる方法で親クラスに密結合されます。
他のすべてのケースでは、それらを消費者/論理的な親と同じ名前空間と同じアクセシビリティ レベルに保つようにしています。多くの場合、「メイン」クラスよりもやや親しみにくい名前を付けています。
大規模なプロジェクトでは、最初または主要な目的が論理的に見えるという理由だけで、強結合コンポーネントを最初に構築する頻度に驚かれることでしょう。他のコンポーネントがそれを使用できるように、クラスを公開しても害はほとんどありません。
編集サブクラスについて話している場合でも、それらは多かれ少なかれ適切に設計され、疎結合されたコンポーネントでなければならないことに注意してください。それらが非公開で外部から見えなくても、クラス間の「表面領域」を最小限に保つことで、将来の拡張や変更に対するコードの保守性が大幅に向上します。
手元にある本はありませんが、フレームワーク設計ガイドラインではpublic
、クライアントがクラス名を参照する必要がない限り、内部クラスを使用することを推奨しています。private
内部クラスは問題ありません。誰もこれらに気付くことはありません。
悪い: ListView.ListViewItemCollection collection = new ListView.ListViewItemCollection();
良い: listView.Items.Add(...);
大規模なクラスについて:一般的に、このようなものを小さなクラスに分割し、それぞれに1つの特定の機能を持たせることは価値があります。最初は分解するのは難しいですが、後であなたの生活が楽になると思います...
一般に、内部クラスはプライベートであり、それらを含むクラスによってのみ使用可能である必要があります。内部クラスが非常に大きい場合は、それらが独自のクラスであることを示唆します。
通常、大きな内部クラスがある場合、それは内部クラスがそれを含むクラスに緊密に結合されており、そのプライベートメソッドにアクセスする必要があるためです。
これはかなり主観的なことだと思いますが、「ホスト」クラスを部分的にすることで、おそらくそれらを別々のコードファイルに分割します。
このようにすることで、プロジェクトファイルを編集して、Windowsフォームのデザイナクラスのようにファイルグループを作成することで、さらに概要を把握できます。これを自動的に実行するVisualStudioアドインを見たことがあると思いますが、どこにあるかは覚えていません。
編集:
いくつか調べた後、VSCommandsと呼ばれるこれを行うためのVisualStudioアドインを見つけました
そのような獣をどのように構築するかについてのみ...
部分クラスを使用して、メイン クラスとネストされたクラスを分割できます。その際、ファイルに適切な名前を付けることをお勧めします。そうすれば、何が起こっているのかが明確になります。
// main class in file Outer.cs
namespace Demo
{
public partial class Outer
{
// Outer class
}
}
// nested class in file Outer.Nested1.cs
namespace Demo
{
public partial class Outer
{
private class Nested1
{
// Nested1 details
}
}
}
ほぼ同じように、(明示的な) インターフェイスが独自のファイルに含まれていることがよくあります。たとえば、それらを ing するOuter.ISomeInterface.cs
エディターのデフォルトではありません。#region
プロジェクトのファイル構造は次のようになります
/Project/Demo/ISomeInterface.cs /Project/Demo/Outer.cs /Project/Demo/Outer.Nested1.cs /Project/Demo/Outer.ISomeInterface.cs
通常、これを行うときは、ビルダー パターンのバリエーション用です。
私は個人的に、ファイルごとに1つのクラスを持ち、そのファイルの一部として内部クラスを持ちたいと思っています。内部クラスは通常(ほぼ常に)プライベートである必要があり、クラスの実装の詳細であると思います。それらを別のファイルに入れると、混乱します、IMO。
この場合、コード領域を使用して内部クラスをラップし、それらの詳細を非表示にすることは、私にとってうまく機能し、ファイルの操作が困難になるのを防ぎます。コード領域は内部クラスを「非表示」に保ちます。これはプライベートな実装の詳細であるため、私にとっては問題ありません。
私は個人的に内部クラスを使用して、クラス内でのみ使用される概念と操作の一部をカプセル化します。このようにして、そのクラスの非公開 API を汚染せず、API をクリーンでコンパクトに保ちます。
部分クラスを利用して、これらの内部クラスの定義を別のファイルに移動して、整理しやすくすることができます。VS は、ASP.NET、WinForm フォームなどの一部のテンプレート化されたアイテムを除いて、部分的なクラス ファイルを自動的にグループ化しません。プロジェクト ファイルを編集し、そこにいくつかの変更を加える必要があります。そこにある既存のグループ化の 1 つを見て、それがどのように行われているかを確認できます。ソリューション エクスプローラーで部分的なクラス ファイルをグループ化できるマクロがいくつかあると思います。
私の意見では、内部クラスは、必要に応じて小さく保ち、そのクラスのみが内部的に使用する必要があります。.NET フレームワークで Relfector を使用すると、その目的のためだけに Relfector が多く使用されていることがわかります。
内部クラスが大きくなりすぎた場合は、保守性のためだけであれば、それらを別のクラス/コードファイルに移動することは間違いありません。内部クラス内で内部クラスを使用することは素晴らしいアイデアだと誰かが考えた既存のコードをサポートする必要があります。その結果、内部クラス階層が 4 ~ 5 レベルの深さで実行されました。言うまでもなく、コードは不可解であり、見ているものを理解するのに何年もかかります。