C#には、クラスの継承をしなくても、既存クラスにメソッドを追加する機能、いわゆる「拡張メソッド」を作ることが出来ます。
拡張メソッドをうまく使えば、コーディングの効率を高めるとともに、可読性も向上するなどのメリットは大きく、使わないのはもったいないです。
そこで、この記事では、拡張メソッドに興味があって、これから使いたいと思う方を対象に、その作り方、使い方、注意点を分かりやすく解説していきます。
拡張メソッドとは
既存のクラスに対して、継承を使わずに追加したメソッドを「拡張メソッド」と呼んでいます。
自分が作ったクラスであれば、後から自由にメソッドが作れますが、C#に組み込まれている String や List 、Array などのクラスについては、おいそれとメソッドを追加できませんよね。
拡張メソッドを使うと、簡単な記述で、これらのクラスに自分の好きなメソッドを追加することができます。
一旦拡張メソッドを作ってしまうと、Visual Studio 上の コード補完機能(IntelliSense)で使えるようになるので、めちゃめちゃ便利になります。

拡張メソッドの作り方
拡張メソッドは難しいとお考えの方もいらっしゃいますが、実は簡単です。
あるルールさえ覚えてしまえば、通常のクラスと同じ様に記述できます。
そのルールとは・・・
記述ルール
さっそく記述方法(ルール)を図にしてみました。
パッと見た感じ、通常の static クラスとほとんど同じですね。
唯一の違いは、メソッドの第一引数の前に this というキーワードが有る点です。

それでは、それぞれの部分について簡単に解説しておきます。
まず、拡張メソッド名は、後々使う事も無いので、何でも構いません。
拡張メソッドはメソッドですから、戻り値の型、メソッド名、引数1、引数2、・・・・という具合に記述します。
大事なのは引数1です。
引数1の前に this というキーワードがありますが、これがあることで拡張メソッドとして振る舞う事ができます。
this の後に続く引数1の方は、拡張したいクラス名(クラスの型)で、次にそれを受ける変数が続きます。
このように記述することで、引数1に拡張したいクラスのオブジェクトが渡ってきますので、後は好きな処理を記述すれば完成です。
サンプルソース
下記は、StringExtention という名前の拡張メソッドを作った場合のサンプルソースです。
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
public static class StringExtention { /// <summary> /// 文字列をbool型に変換する。変換できなかった場合、 alternativeValue を返す。 /// alternateValueの初期値は false。 /// </summary> /// <param name="self"></param> /// <param name="alternativeValue"></param> /// <returns></returns> public static bool ToBool(this string str, bool? alternativeValue = null) { return (bool.TryParse(str, out bool value) ? value : alternativeValue??false); } /// <summary> /// 文字列をint型に変換する。変換できなかった場合、 alternativeValue を返す。 /// alternateValueの初期値は 0。 /// </summary> /// <param name="str"></param> /// <param name="alternativeValue"></param> /// <returns></returns> public static int ToInt(this string str, int? alternativeValue = null) { return (int.TryParse(str, out int value) ? value : alternativeValue??0); } /// <summary> /// 文字列をdouble型に変換する。変換できなかった場合、 alternativeValue を返す。 /// alternateValueの初期値は double.NaN。 /// </summary> /// <param name="str"></param> /// <param name="alternativeValue"></param> /// <returns></returns> public static double ToDouble(this string str, double? alternativeValue = null) { return (double.TryParse(str, out double value) ? value : alternativeValue??double.NaN); } /// <summary> /// 文字列を日付型に変換する。変換できなかった場合、 alternativeValue を返す。 /// alternateValueの初期値は DateTime.MaxValue。 /// </summary> /// <param name="str"></param> /// <param name="alternativeValue"></param> /// <returns></returns> public static DateTime ToDateTime(this string str, DateTime? alternativeValue = null) { return (DateTime.TryParse(str, out DateTime value) ? value : alternativeValue??DateTime.MinValue); } /// <summary> /// 文字列をString.Formatのフォーマット文字に見立て、可変長引数を渡して文字列を作成する /// </summary> /// <param name="str"></param> /// <param name="args"></param> /// <returns></returns> public static string Args(this string str, params object[] args) { return string.Format(str, args); } } |
拡張メソッドの使い方
拡張メソッドは普通のメソッドとまったく同じなので、ピリオド(.)を付けて記述します。
例えば、先ほど紹介したサンプルの中にあるToDoubleというメソッドがありました。
これは、引数1(this string str)と 引数2(alternativeValue) が指定されています。
1 2 3 4 5 |
public static double ToDouble(this string str, double? alternativeValue = null) { return (double.TryParse(str, out double value) ? value : alternativeValue??double.NaN); } |
これを使う場合、次の様に記述します。
1 |
double val = "12345.8".ToDouble(0); |
引数1は拡張メソッドの定義の際に使用するものなので、使う場合は引数2以降を渡します。
ToDoubleの引数1(定義の際の引数2)に0を指定していますので、 alternativeValue は0が代入されます。
勿論、省略可能なので省略することも可能です。
拡張メソッドが適用できるクラス
拡張メソッドは static class ではありますが、拡張したいクラスは static でなくても問題ありません。
例えば、次のようなケースでは、new して使う MyClass に対して拡張メソッドを作っていますが、ちゃんとコード補完機能(IntelliSense)に拡張メソッド(MyExtention)が表示されていますね。

拡張メソッドの注意点
便利な拡張メソッドですが、次の様なリスクもあります。
- 不用意に使いすぎると、どこにどんな拡張メソッドをつくったかが分からなくなる
- 拡張メソッドと同じメソッド名が、元のクラスに実装されたとき、元のクラスのメソッドが優先されます。
- 派生クラス全てに対して拡張メソッドが有効になるので、派生メソッド側で同じメソッド名が作られても実行されない
要するに、乱用は禁物ということだけ注意しておきましょう。
まとめ
今回は拡張メソッドについて解説しました。
継承を使わず既存のクラスにメソッドを拡張できる点は、非常に便利です。
乱用は禁物ですが、効果的に使うと生産性や可読性の向上に役立ちます。
作り方は簡単なので、是非ご活用下さい。