この記事では、あらゆる .NET 型を対象に独自の拡張メソッドを実装する方法について説明します。 クライアント コードでは、独自の拡張メソッドを使用できます。 クライアント プロジェクトは、それらを含むアセンブリを参照する必要があります。 クライアント プロジェクトでは、拡張メソッドが定義されている名前空間を指定する using ディレクティブを追加する必要があります。
C# 14 以降では、拡張メソッドの定義に使用できる 2 つの構文があります。 C# 14 では 拡張ブロックが 追加されます。ここで、型の拡張メンバーを定義します。 C# 14 より前のバージョンでは、 静的 メソッドの最初のパラメーターにこの修飾子を追加して、メソッドがパラメーター型のインスタンスのメンバーとして表示されることを示します。
拡張ブロック (C# 14 以降)
C# 14 以降では、拡張ブロックを使用して 拡張メソッドを宣言できます。 拡張ブロックは、型またはその型のインスタンスの拡張メンバーを含む、入れ子になっていない非ジェネリックの静的クラスのブロックです。
拡張ブロックを使用して拡張メソッドを定義して呼び出すには:
- 拡張メソッドを格納するための静的クラスを定義します。 クラスは、クライアント コードから参照できる必要があります。別の型内に入れ子にすることはできません。 アクセシビリティの規則の詳細については、「アクセス修飾子」を参照してください。
- 拡張ブロックを使用して、型の拡張メンバーを宣言します。
- 呼び出し元のコードで、
usingディレクティブを追加して、拡張メソッドのクラスを含む名前空間を指定します。 - メソッドを型のインスタンス メソッドとして呼び出します。
次の例では、C# 14 拡張ブロック構文を使用して、 WordCount という名前の拡張メソッドを実装します。 このメソッドは、 String クラスで動作します。
CustomExtensions名前空間はアプリケーション名前空間にインポートされ、メソッドは文字列のインスタンス メソッドであるかのように呼び出されます。
using CustomExtensions;
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine($"Word count of s is {i}");
namespace CustomExtensions
{
// Extension methods must be defined in a static class.
public static class StringExtension
{
extension(string str)
{
// This is the extension member.
// The `str` parameter is declared on the extension declaration.
public int WordCount()
{
return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
}
拡張メソッド (以前のバージョン)
C# 14 より前のバージョンでは、 この 修飾子を静的メソッドの最初のパラメーターに追加して拡張メソッドを宣言しました。
クラシック構文を使用して拡張メソッドを定義して呼び出すには:
- 拡張メソッドを格納するための静的クラスを定義します。 クラスは、クライアント コードから参照できる必要があります。別の型内に入れ子にすることはできません。 アクセシビリティの規則の詳細については、「アクセス修飾子」を参照してください。
- 拡張メソッドを静的メソッドとして実装します。メソッドの可視性は、包含クラスと同レベル以上を指定します。
- メソッドの最初のパラメーターでは、メソッドが操作する型を指定します。型名の前には this 修飾子を付加します。
- 呼び出し元のコードで、
usingディレクティブを追加して、拡張メソッドのクラスを含む名前空間を指定します。 - メソッドを型のインスタンス メソッドとして呼び出します。
次の例では、クラシック構文を使用して WordCount という名前の拡張メソッドを実装します。 このメソッドは、 String クラスを操作します。このクラスは、 this 修飾子を持つ最初のメソッド パラメーターとして指定されます。
CustomExtensions名前空間はアプリケーション名前空間にインポートされ、メソッドは文字列のインスタンス メソッドであるかのように呼び出されます。
using CustomExtensions;
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine($"Word count of s is {i}");
namespace CustomExtensions
{
// Extension methods must be defined in a static class.
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type to be extended.
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
Note
最初のパラメーターは、メソッドが適用されている型を表し、コンパイラがオブジェクトの型を既に認識しているため、コードを呼び出すことによって指定されません。 指定する必要があるのは、2 番目から n 番目のパラメーターの引数だけです。
全般情報
オーバーロードの解決では、型自体によって定義されたインスタンスメソッドまたは静的メソッドが拡張メソッドよりも優先されます。 拡張メソッドは、拡張されたクラスのプライベート データにはアクセスできません。
関連項目
.NET