
C#の拡張メソッドとは?引用thisやサンプルをご紹介
- SE
- C#の拡張メソッドとはどのようなものでしょうか。
- PM
- C#の拡張メソッドとはstaticメソッドをインスタンスメソッドと同じ形式で呼び出せるようにできるものです。
目次
C#の引数thisについて
今回は、C#での引数thisについて説明します。引数thisを付けたメソッドを拡張メソッドといいます。
拡張メソッドは、staticメソッドをインスタンスメソッドと同じ形式で呼び出せるようにできるものです。C#での拡張メソッドに興味のある方はぜひご覧ください。
拡張メソッドとは
C#拡張メソッドは、staticメソッドをインスタンスメソッドと同じ形式で呼び出せるようにできるものです。既存の型の変更や継承をせずに、新たなメソッドを追加することができます。
これまでは、
1 2 3 |
string str = Extensions.AddString(""hoge""); |
と書いていたものを、
1 2 3 4 5 6 7 8 9 |
static class Extensions { public static string AddString(this string str, string addStr) { return str + addStr; } } |
というようなstaticメソッドを用意することで、以下のように呼び出せるようになります。定義側では、第1引数の前にthisキーワードを付けます。その1つ目の引数が、拡張メソッドを使う値自身のことを指すことになります。
staticのクラスの中に拡張メソッドを作りましょう。
1 2 3 |
string str = ""hoge"".AddString(""hoge""); |
このように、利用側ではインスタンスメソッドと同じ書き方をします。
拡張メソッドのサンプル
C#の拡張メソッドの定義側、利用側をまとめたサンプルを示します。
文字列に引数の文字列を連結して返却します。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System; namespace ConsoleApplication1 { static class StringExtensions { /// <summary> /// 引数の文字列を連結する。 /// </summary> /// <param name=""str"">連結文字列</param> /// <param name=""addStr"">連結文字列</param> /// <returns>連結結果</returns> public static string AddString(this string str, string addStr) { return str + addStr; } } class ExtensionMethodTest { static void Main(string[] args) { string str = ""hoge""; Console.WriteLine(str.AddString(""hoge"")); Console.WriteLine(""hoge"".AddString(""piyo"")); } } } |
実行結果は以下のようになります。
1 2 |
hogehoge hogepiyo |
このように、staticメソッドをインスタンスメソッドと同じ形式で呼び出せていることが分かります。
同じ名前空間内に2つ以上同名の拡張メソッドを定義できない
後述しますが、拡張メソッドは、「using ディレクティブ」で指定した名前空間中のにある拡張メソッドが参照されます。
そのため、C#では同じ名前空間内に2つ以上同名の拡張メソッドを定義できません。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 |
using System; namespace ConsoleApplication1 { static class StringExtensions { /// <summary> /// 引数の文字列を連結する。 /// |
/// <param name=””str””>連結文字列</param> /// <param name=””addStr””>連結文字列</param> /// <returns>連結結果</returns> public static string AddString(this string str, string addStr) { return str + addStr; } } static class StringExtensions2 { /// <summary> /// 引数の文字列を連結する。 ///
/// <param name=””str””>連結文字列</param> /// <param name=””addStr””>連結文字列</param> /// <returns>連結結果</returns> public static string AddString(this string str, string addStr) { return str + addStr; } } class ExtensionMethodTest { static void Main(string[] args) { string str = “”hoge””; Console.WriteLine(str.AddString(“”hoge””)); Console.WriteLine(“”hoge””.AddString(“”piyo””)); } } }
1 |
この場合、コンパイルエラーになります。
C#では同じ名前空間内に2つ以上同名の拡張メソッドを定義してはいけません。別の名前空間であれば、同名の拡張メソッドを定義できます。
定義側と利用側で名前空間を分ける
拡張メソッドは、「using ディレクティブ」で指定した名前空間中のにある拡張メソッドが参照されるようになっています。
以下の例のように、利用側で「using MyExtensions;」と記述する必要があります。定義側と利用側が別の名前空間の場合の利用方法を見てみましょう。
定義側
1 2 3 4 5 6 7 8 |
namespace MyExtensions { static class StringExtensions { /// <summary> /// 引数の文字列を連結する。 /// |
/// <param name=””str””>連結文字列</param> /// <param name=””addStr””>連結文字列</param> /// <returns>連結結果</returns> public static string AddString(this string str, string addStr) { return str + addStr; } } }
1 |
利用側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System; using MyExtensions; namespace ConsoleApplication1 { class ExtensionMethodTest { static void Main(string[] args) { string str = ""hoge""; Console.WriteLine(str.AddString(""hoge"")); Console.WriteLine(""hoge"".AddString(""piyo"")); } } } |
実行結果は以下のようになります。
1 2 |
hogehoge hogepiyo |
このように、拡張メソッドは、「using ディレクティブ」で指定した名前空間中のにある拡張メソッドが参照されます。
優先順位
C#の拡張メソッドと通常のインスタンスメソッドが同名の場合、どうなるでしょうか。拡張メソッドよりも通常のインスタンスメソッドの方が優先されます。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 |
using System; namespace ConsoleApplication1 { static class StringExtensions { /// <summary> /// 引数の文字列に""hoge""を連結する。 /// |
/// <param name=””value””>連結文字列</param> /// <returns>連結結果</returns> public static string ToSting(this int value) { return value.ToString() + “”hoge””; } } class ExtensionMethodTest { static void Main(string[] args) { int value = 1; Console.WriteLine(value.ToString()); } } }
1 |
実行結果は以下のようになります。
1 |
1 |
このように、C#では拡張メソッドよりも通常のインスタンスメソッドの方が優先されます。
- SE
- 同じ名前空間内に2つ以上同名の拡張メソッドを定義できないのですね。
- PM
- そのとおりです。ぜひご自身でC#のソースコードを書いてみましょう。
C#における拡張メソッドの理解を深めよう
C#では、引数thisを付けたメソッドを拡張メソッドといいます。拡張メソッドは、staticメソッドをインスタンスメソッドと同じ形式で呼び出せるようにできるものです。
ぜひご自身でC#のソースコードを書いて、理解を深めてください。