拡張メソッド
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 39/70。
拡張メソッドを使用すると、既存の型のソースコードを変更したり、派生クラスを作成したりすることなく、その型に新しいメソッドを追加できます。これらはその型のネイティブメソッドであるかのように表示されるため、コードがより読みやすく、直感的になります。
拡張メソッドを作成するには、静的クラス内に静的メソッドを定義し、最初のパラメータの前に this キーワードを付けます:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}これで、任意の文字列に対してこのメソッドを直接呼び出すことができます:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3this string str パラメーターは、このメソッドが string 型を拡張することをコンパイラに伝えます。sentence.WordCount() を呼び出すと、コンパイラは背後でそれを StringExtensions.WordCount(sentence) に変換します。
拡張メソッドは、追加のパラメータを受け取ることもできます:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
// 使用例
bool result = "Hello".IsLongerThan(3); // trueこの手法はLINQで広く使用されており、Where() や Select() といったメソッドは IEnumerable の拡張メソッドです。拡張メソッドは、自分が制御していない型にユーティリティ機能を追加するのに非常に強力で、コードをクリーンで表現力豊かな状態に保つことができます。
チャレンジ
簡単整数に対して、組み込み機能として期待されるような便利な機能を追加する一連の拡張メソッドを作成しましょう。任意の整数に対して直接呼び出すことができる拡張メソッドを含む静的クラスを作成し、コードをより表現力豊かで読みやすいものにします。
コードは2つのファイルに分けて構成します:
IntExtensions.cs:Utilities名前空間内にIntExtensionsという名前の静的クラスを作成します。このクラスには、int型を拡張する以下の拡張メソッドを含めます:IsEven()- 数値が偶数の場合はtrue、そうでない場合はfalseを返します。Square()- 数値を自乗した結果を返します。IsInRange(int min, int max)- 数値が min と max の間(両端を含む)にある場合はtrue、そうでない場合はfalseを返します。
thisキーワードを使用して、どの型を拡張するかを指定することを忘れないでください。Program.cs: メインファイルで、入力から整数を読み取り、3つの拡張メソッドすべてを実演します。各メソッドを、あたかも組み込みメソッドであるかのように整数に対して直接呼び出し、結果を出力してください。
3つの入力を受け取ります:
- テストする数値(整数)
- 範囲チェックの最小値(整数)
- 範囲チェックの最大値(整数)
出力は以下の形式で表示してください:
Is {number} even? {True/False}
Square of {number}: {result}
Is {number} in range [{min}-{max}]? {True/False}例えば、入力が 7、5、10 の場合、出力は以下のようになります:
Is 7 even? False
Square of 7: 49
Is 7 in range [5-10]? Truenumber.IsEven() や number.Square() といかに自然に記述できるかに注目してください。拡張メソッドによって、それらが最初から整数型の一部であったかのように感じられます!
チートシート
拡張メソッドを使用すると、既存の型のソースコードを変更することなく、その型に新しいメソッドを追加できます。これらは静的クラス内の静的メソッドとして定義する必要があり、最初のパラメータの前に this キーワードを記述します。
基本的な拡張メソッドの構文:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}使用法:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3最初のパラメータの前にある this キーワードは、どの型が拡張されているかを示します。コンパイラは sentence.WordCount() を StringExtensions.WordCount(sentence) に変換します。
追加のパラメータを持つ拡張メソッド:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
bool result = "Hello".IsLongerThan(3); // true自分で試してみよう
using System;
using Utilities;
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
int number = Convert.ToInt32(Console.ReadLine());
int min = Convert.ToInt32(Console.ReadLine());
int max = Convert.ToInt32(Console.ReadLine());
// TODO: 'number' に対して拡張メソッドを使用し、結果を出力する
// number.IsEven()、number.Square()、および number.IsInRange(min, max) を呼び出す
// 次の形式で出力する:
// Is {number} even? {True/False}
// Square of {number}: {result}
// Is {number} in range [{min}-{max}]? {True/False}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。