C#の拡張メソッドとは?引用thisやサンプルをご紹介

- システム
エンジニア - C#の拡張メソッドとはどのようなものでしょうか。
- プロジェクト
マネージャー - 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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
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;
}
}
static class StringExtensions2
{
/// <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"));
}
}
}
|
この場合、コンパイルエラーになります。
C#では同じ名前空間内に2つ以上同名の拡張メソッドを定義してはいけません。別の名前空間であれば、同名の拡張メソッドを定義できます。
定義側と利用側で名前空間を分ける
拡張メソッドは、「using ディレクティブ」で指定した名前空間中のにある拡張メソッドが参照されるようになっています。
以下の例のように、利用側で「using MyExtensions;」と記述する必要があります。定義側と利用側が別の名前空間の場合の利用方法を見てみましょう。
定義側
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
namespace MyExtensions
{
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;
}
}
}
|
利用側
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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
using System;
namespace ConsoleApplication1
{
static class StringExtensions
{
/// <summary>
/// 引数の文字列に"hoge"を連結する。
/// </summary>
/// <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
|
このように、C#では拡張メソッドよりも通常のインスタンスメソッドの方が優先されます。
- システム
エンジニア - 同じ名前空間内に2つ以上同名の拡張メソッドを定義できないのですね。
- プロジェクト
マネージャー - そのとおりです。ぜひご自身でC#のソースコードを書いてみましょう。
C#における拡張メソッドの理解を深めよう
C#では、引数thisを付けたメソッドを拡張メソッドといいます。拡張メソッドは、staticメソッドをインスタンスメソッドと同じ形式で呼び出せるようにできるものです。
ぜひご自身でC#のソースコードを書いて、理解を深めてください。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)