web-dev-qa-db-ja.com

部分クラスと拡張メソッド

これらの2つの方法を使用してクラスを拡張したり、クラスに対して拡張メソッドを作成したりした経験はあまりありません。他の人の作品を見て、ここで質問があります。

プロジェクトでエンティティクラスを拡張するために部分クラスを使用している人々を見ました。一方、同じプロジェクトには、エンティティクラスへの多くの拡張メソッドを含む別のフォルダがあります。

そうするのは正しいですか?つまり、これら2つの方法はどちらもうまく機能します。クラスを拡張したいときにどちらを選ぶかについて、実際のアイデアを教えてください。

41
ValidfroM

部分クラスと拡張メソッドのどちらを使用するかを決定するいくつかの違いは次のとおりです。

部分クラス

  • 同じプロジェクト/アセンブリ内のクラスに対してのみ機能します
  • ターゲットクラスは部分としてマークする必要があります
  • ターゲットクラスのフィールドと保護されたメンバーにアクセスできます
  • ターゲットはクラス実装である必要があります

拡張方法

  • 他のアセンブルのクラスに適用できます
  • 静的である必要があり、ターゲットクラスのパブリックメンバーにのみアクセスできます
  • 拡張のターゲットは、具象型、抽象型、またはインターフェースにすることができます
39
Jaimal Chohan

コード生成シナリオでは、部分クラスを使用する必要があります。

生成されたファイルはいつでも上書きされる可能性があるため、部分クラスを使用して生成されていないファイルに書き込みます。

さらに、パーシャルは同じアセンブリの一部である場合にのみ機能します。アセンブリの境界を越えることはできません。

これらが制約ではない場合は、拡張メソッドを使用できます。もちろん、継承や構成などの他の可能性を考慮して、適合性を確認してください。

25
Oded

NULLインスタンスでは拡張メソッドを使用できますが、(部分クラスなどの)インスタンスメソッドでは使用できません。これは、拡張メソッドが実際には静的である結果です。

3
Ron Newcomb

部分的に機能するのは、両方のファイルが同じプロジェクトにあり、そのクラスのプライベートメンバーと保護されたメンバーにアクセスできる場合のみです。

拡張メソッドは単なる静的メソッドであり、プライベートメンバーにアクセスすることはできません。

したがって、プライベートメンバーと保護されたメンバーにアクセスする場合は、部分的な方法しかありません。いいえの場合は、質問に答えてください。追加するメソッドは、クラスを使用するすべての場所に表示する必要がありますか?はいの場合は部分的を使用し、いいえの場合はある種の拡張であり、拡張メソッドを使用します。

ちなみに、最初のクラスが何らかのツールで生成されていない場合は、部分的な;)を使用する以外は、そこに関数を記述できます。

お役に立てれば

2
Arsen Mkrtchyan

インターフェイスを実装するためのクラスが必要な場合は部分メソッドを使用しますが、クラスコードは自動生成されます(VSは部分クラスを使用してWebサービスとEFモデルの両方のコードを生成します)。

タイプに追加する新しいメソッドがそのタイプのany値に適している場合は、拡張メソッドを使用します。 (良い例:int.IsEven()、string.IsEmpty();悪い例:int.IsOldEnoughToDrive()、string.IsLastName())。

2
lance

開発中のプロジェクトで部分クラスを使用できますが、拡張メソッドを使用して、ソースコードがないプロジェクトを拡張することもできます。

2
Marco

部分クラスルートを選択したが、同じコードを繰り返していることがわかった場合は、拡張メソッドに切り替えます。

たとえば、IEnumerable<Track>データを返すメソッドで生成されたクラスがたくさんあります。 IEnumerable<MediaItem>の形式でデータを受信するオプションを提供するために、各クラスを何らかの方法で拡張したいと思います。

ここでは、IEnumerable<Track>データをIEnumerable<MediaItem>に変換するための一般的な要件があります。この場合、複数のpartial classメソッドを作成するよりも、拡張メソッドが最適です。

public static class ExtensionMethods
{
    public static IEnumerable<MediaItem> ToMediaItems(this IEnumerable<Track> tracks)
    {
        return from t in tracks
               select new MediaItem
               {
                   artist = t.Artist,
                   title = t.Title,
                   // blah blah
               };
    }
}

これにより、次のオプションが得られます。

var data = Playlist.Tracks.ToMediaItems();
var data = Podcast.Tracks.ToMediaItems();
// etc..
1
Lloyd

部分クラスは、生成されたクラスを拡張する場合に役立ちます。このようにして、1つのファイルにコードを記述し、クラスの他の「部分」を再生成する必要がある場合、そのコードファイルは変更されていないため、安全に実行できます。

0
Paddy
Partial Class - 

クラスまたは構造体、あるいはインターフェースの定義を2つ以上のソースファイルに分割する

Extension Method  

拡張メソッドを使用すると、新しい派生型を作成したり、再コンパイルしたり、元の型を変更したりすることなく、既存の型にメソッドを「追加」できます。

0
anishMarokey