web-dev-qa-db-ja.com

なぜ部分クラスを使用するのですか?

私の理解では、partialキーワードはクラスを複数のソースファイルに分割することしかできません。コード編成以外にこれを行う理由はありますか?生成されたUIクラスでそれを使用するのを見てきました。

キーワード全体を作成するのはよくない理由のようです。クラスが複数のファイルを必要とするほど大きい場合は、多すぎます。他のプログラマがどこかで完成させるクラスを部分的に定義するのに使えるかもしれないと思いましたが、抽象クラスを作る方がいいでしょう。

72
Michael K

生成されたクラスを継承せずに生成されたコードにカスタムロジックを追加できるため、クラスの一部がカスタムツールによって生成されるすべてのシナリオで非常に役立ちます。ところで同じ理由で部分的な方法もあります。

UIだけでなく、Linq-To-SqlやEntity Frameworkのような他のテクノロジーもこれを多用しています。

113
Ladislav Mrnka

あなたが言うように、それはしばしば生成されたコードを分離するために使用されます。多くの場合、クラス/ファイルのサイズとは関係ありません。

生成されたコードを分離する利点は、スタイルの1つです。生成されたコードは見苦しくて読みにくく、多くのコーディング標準(およびStyleCopチェック)に失敗しますが、それを読んだり、直接管理したりする必要はありません。したがって、別のファイルで「非表示」にすると、クラスの残りの部分が標準に準拠していることを確認したり、StyleCopチェックに合格したりすることに集中できます。

私が使用したもう1つの領域は、クラスが複数のインターフェースを実装する場所です。実装を個別のファイルに分離するのは非常に良いことです。または防止)これ。

26
Steve

私が働いている開発者の1人が、数週間前に、制御不能になり、多くのパブリックメソッドを持つ巨大な神のクラスのリファクタリングでかなり有効に利用できるようになりました。クラスを個別の部分クラスに分割することで、既存の機能を損なうことなく、クラスを物理的によりアトミックな単位に分離できるため、一般的なものとそうでないものを確認できます。これを最初のステージとして使用すると、パーシャルを独自の独立したクラスに簡単に分割し、コードベース全体に実装できます。これはいい考えだと思いました。

ただし、一般に、新しいコードを作成するときに、マシンで生成されたクラスを拡張するためにのみ使用する必要があると思います。

19
user23157

パーシャルが理にかなっているいくつかの便利なシナリオを考えることができます。それらのほとんどは自分のプロジェクトで使用しています。

  • 保守しているコードからTool/IDE/Designer生成コードを分離するには良い例は、Windowsフォームアプリケーション用にデザイナーが生成したコードを含むForm.Designer.csファイルです。他の多くの.NET形式にもいくつかのツールで生成されたコードがあり、プロジェクトのビルド時にコードが再生成される可能性があるため、カスタムの変更はすべて破棄されます。分離は、コードや変更をこのような自動化された変更から安全に保つのに役立ちます。

  • 複数のインターフェースを実装する場合、実装に多くのコードを使用します。私はそのようなインターフェースごとに個別の部分ファイルを使用する傾向があり、次のように命名します:{Class}.{Interface}.cs。 IDEで、{Class}が実装しているインターフェイスとその方法を確認するのは簡単です。

  • クラスに1つ以上のネストされたクラスを含める必要がある場合(特に、別のファイルに配置するのに十分なコードがある場合)。上記のパターンに固執し、ネストされたクラスごとに{Class}.{NestedClass}.cs命名規則を使用します。 Virtlink's answer でも同様の方法について述べています。

  • 拡張メソッドを保持するstaticクラスを書くとき。ジェネリックコレクションと非ジェネリックコレクションのインスタンスReverseのように、同じ拡張メソッドロジックを類似のクラスまたはインターフェイスに提供することがよくあります。単一のクラスまたはインターフェイスのすべての拡張メソッドを静的クラスの別の部分に配置します。たとえば、IListインターフェイスのすべての拡張メソッドが1か所にあり、IList<T>と同じメソッドが別のファイルにあります。別のアプローチは、同じメソッド(そのオーバーロードのすべて)を同じパーシャルに配置することです。thisパラメータのすべての可能なクラス-1つのファイルにすべてのReverse実装があるように。それは、コード量の観点から、またはあなたやあなたの組織が固執しているかもしれないいくつかの内部規約に関して、どちらがより適切に分離を正当化するかに依存します。

  • 私はこれを使用しませんが、ここで説明するアプローチを気に入っているC/C++の人々を見てきました:partial methodsのみ。これは、インターフェイスを定義し、メソッド宣言を実装から分離するC/C++の方法に似ています。

  • 純粋な論理的懸念による分離。それ自体で複数の論理的な操作のセットを組み合わせる大きなクラスで作業する場合、論理的に関連する各コードを個別のパーシャルに分離できます。通常、このようなクラスの存在は懸念の分離原則に反しますが、特に古いコードベースでは、実際のケースでよく見られます。他のユーザーであるSteve Eversが この質問に対する彼の回答 で言及し、god objectsの名前でそれらを参照しています。個人的には、部分クラスのアプローチを使用して、非常に大きなファイルのリファクタリングが行われる前にコードを分割して、作業を容易にし、リファクタリングをより透過的にします。これにより、SVNのようなバージョン管理システムが関与している場合に発生する可能性がある競合も軽減されます。

19
Ivaylo Slavov

私はそれが誰からも言及されたのを見たことはありません。私はpartialを使用して、ネストされたクラスを独自のファイルに入れています。

すべてのコードファイルには、クラス、構造体、インターフェイス、または列挙型が1つだけ含まれています。ファイル名が探しているものの名​​前を示していると、オブジェクトの定義を見つけやすくなります。また、Visual Studioはプロジェクトフォルダーを名前空間に一致させようとするため、ファイル名はクラスに一致する必要があります。

これは、NestedClass内にネストされたクラスMyClassが、自分のプロジェクトに独自のファイルを持つことも意味します:MyClass.NestedClass.cs

partial class MyClass
{
    private class NestedClass
    {
        // ...
    }
}

生成されたコードを使用することを除いて、私はonlyを使用して、 god objects をカバーするために使用されているのを見たことがあります。新しいコードベースを理解したり、同じオブジェクトである複数のソースファイル間を移動したりするのは、非常に面倒です。

したがって、Why use partial classes?私が答えます。生成されたコードを使用しているのでない限り、使用しないでください。

10
Steven Evers

コード編成が唯一の理由ですが、それは最初に思われるよりも深くなります。パーツが生成される部分クラスがある場合、簡単に次のことができます。

  • 書き込むクラスの手動変更を検出せずにコードを再生成します(そのため、これらの部分を上書きしないようにします)。
  • 生成された部分クラスをテストカバレッジ、ソース管理、メトリックなどから除外します。
  • 生成されたコードを使用して、継承戦略のベースを強制することはありません(他のクラスから継承することもできます)。
6
Deckard

汚い使い方が考えられます。

共通の機能を必要とするクラスがいくつかあるが、その機能をそれらの上の継承チェーンに挿入したくない場合を考えます。または、共通のヘルパークラスを使用するクラスのセットがあります。

基本的に、多重継承を行いたいが、C#は似ていない。つまり、部分的なものを使用して、基本的にはC/C++の#includeを作成します。

すべての機能をクラスに入れるか、ヘルパークラスを使用します。次にヘルパーをX回コピーし、名前を部分クラスA、B、Cに変更します。 A、B、Cクラスにパーシャルを置きます。

免責事項:はい、これは悪です。他の人があなたを怒らせるような場合は特に、絶対にしないでください。

1
Mark

生成された/暗黙のクラスが部分的に宣言される場所もいくつかあります。開発者がそれらを拡張する必要がある場合、場所全体の継承とオーバーライドについて混乱する必要なく、それらに完全なアクセス権があります。いくつかの例をキャッチしたい場合は、IIS)で初めてWebフォームサイトを実行した後、asp.net一時領域で生成されたクラスを確認してください。

1
Bill