拡張メソッドは、他の方法では実行できないものを提供しません。それらは、実際の技術的な利点を提供することなく、開発をより良くするための構文上の砂糖です。
拡張メソッドは比較的新しいものです。標準と慣例は通常、世論(および何が悪い考えになるかについての長期的な経験)によって決定され、誰もが同意する明確な線を引くことができるようになったとは思いません。
しかし、同僚から聞いたことに基づいて、いくつかの議論を見ることができます。
1.通常、それらは静的メソッドを置き換えます。
エクステンションメソッドは、クラスメソッドではなく、静的メソッドであることに基づいています。それらはクラスメソッドのように見えますが、実際にはそうではありません。
拡張メソッドは、クラスメソッドの代替と見なすべきではありません。むしろ、構文的にはugleの静的メソッドに「クラスメソッド」のルックアンドフィールを与える方法として。
2.目的の方法が、ソースライブラリではなく、消費プロジェクトに固有である場合。
ライブラリとコンシューマーの両方を開発したからといって、適切な場所にロジックを配置しても構わないとは限りません。
例えば:
- あなたは持っている
PersonDto
クラスは、あなたからのDataLayer
プロジェクト。
- あなたの
WebUI
プロジェクトが変換できるようにしたいと考えてPersonDto
しますPersonViewModel
。
この変換方法をDataLayer
プロジェクトに追加することはできません(したくありません)。このメソッドのスコープはWebUI
プロジェクトであるため、そのプロジェクト内に存在する必要があります。
拡張メソッドを使用すると、DataLayer
ライブラリに実装することなく、プロジェクト(およびプロジェクトのコンシューマー)内でこのメソッドにグローバルにアクセスできます。
3.データクラスにデータのみを含める必要があると思われる場合。
たとえば、Person
クラスには人物のプロパティが含まれています。ただし、一部のデータをフォーマットするいくつかのメソッドを使用できるようにしたいとします。
public class Person
{
//The properties...
public SecurityQuestionAnswers GetSecurityAnswers()
{
return new SecurityQuestionAnswers()
{
MothersMaidenName = this.Mother.MaidenName,
FirstPetsName = this.Pets.OrderbyDescending(x => x.Date).FirstOrDefault()?.Name
};
}
}
クラスでデータとロジックを混ぜるのが嫌いな同僚をたくさん見ました。データのフォーマットなどの単純なことに同意することはできませんが、上記の例では、Person
に依存する必要があるのは不快だと思いSecurityQuestionAnswers
ます。
このメソッドを拡張メソッドに配置すると、純粋なデータクラスを破壊するのを防ぐことができます。
この引数はスタイルの1つであることに注意してください。これは部分クラスに似ています。そうすることには技術的なメリットはほとんどありませんが、コードがよりクリーンであると考える場合(たとえば、多くの人がクラスを使用しているが、追加のカスタムメソッドは気にしない場合)、コードを複数のファイルに分離できます。
4.ヘルパーメソッド
ほとんどのプロジェクトでは、ヘルパークラスを作成する傾向があります。これらは通常、簡単なフォーマットのためのメソッドのコレクションを提供する静的クラスです。
たとえば、私が働いていたある会社には、使用したい特定の日時形式がありました。すべての場所にフォーマット文字列を貼り付けたり、フォーマット文字列をグローバル変数にしたりする代わりに、DateTime拡張メソッドを選択しました。
public static string ToCompanyFormat(this DateTime dt)
{
return dt.ToString("...");
}
通常の静的ヘルパーメソッドよりも優れていますか?私はそう思う。構文をクリーンアップします。の代わりに
DateTimeHelper.ToCompanyFormat(myObj.CreatedOn);
私はそれをできた:
myObj.CreatedOn.ToCompanyFormat();
これは、同じ構文の流暢なバージョンに似ています。どちらか一方を持っていることによる技術的なメリットはありませんが、私はもっと好きです。
これらの議論はすべて主観的です。それらのいずれもそうでなければカバーすることができなかったケースをカバーしません。
- すべての拡張メソッドは、通常の静的メソッドに簡単に書き直すことができます。
- 拡張メソッドが存在しなくても、コードは部分クラスを使用してファイルに分離できます。
しかし、繰り返しになりますが、これらは極端に必要なものではないというあなたの主張を受け入れることができます。
- 特定のクラス用であることを明確に示す名前を持つ静的メソッドを常に作成できるのに、なぜクラスメソッドが必要なのでしょうか。
この質問とあなたの質問への答えは同じです。
- より良い構文
- 可読性の向上とコードペダントリの削減(コードは少ない文字数でポイントに到達します)
- Intellisenseは、コンテキスト上意味のある結果を提供します(拡張メソッドは正しいタイプでのみ表示されます。静的クラスはどこでも使用できます)。
ただし、特筆すべき点は次のとおりです。
- 拡張メソッドは、メソッドチェーンのコーディングスタイルを可能にします。これは、よりバニラなメソッドのラッピング構文とは対照的に、最近人気が高まっています。同様の構文設定は、LINQのメソッド構文で見ることができます。
- メソッドチェーンはクラスメソッドを使用しても実行できますが、これは静的メソッドにはまったく当てはまらないことに注意してください。拡張メソッドは、通常、クラスメソッドではなく静的メソッドであるはずのものに基づいています。