C#には、元の型の変更を行うことなく既存の型にメソッドを “追加” できます。
そういうメソッドを「拡張メソッド」と呼びます。
拡張メソッドは特別な種類の静的メソッドですが、拡張された型のインスタンス メソッドのように呼び出して使うことができます。
拡張メソッドの作り方
クラスとメソッドはstaticにしておき、メソッドの引数にはthisをつける。
この方法で拡張メソッドを作ることができます。
基本的なルールは下記のようになります。
- 拡張メソッドを持つクラスは、staticクラスとする。
- 拡張メソッドは、必ずstaticメソッドにする。
- 最低必ず一つの引数を受け取るようにする。
- 宣言する拡張メソッドの第一引数は必ず次のような書式にする。
public static 戻り値型 拡張メソッド名(this 拡張するクラスの型 obj)
作ったクラスを使うには、作成した拡張クラスをusingでインポートするだけです。
サンプルコード
stringクラスで、現在の値をコンソールに表示するメソッドを追加する拡張メソッドを作る場合は、下記サンプルのようになります。
public static class ExtMethodClass { public static void Display(this string s) { Console.WriteLine(s); } } class Program { static void Main(string[] args) { string s = "文字列"; s.Display(); } }
このプログラムをビルドして実行すると、コンソールに”文字列”(string型変数’s’に代入した値)と表示されます。
同じ機能を他のクラスにも「拡張」してみる
先ほどのDisplayメソッドをint型でも使ってみたい時は、下記のように追加するだけです。
public static class ExtMethodClass { public static void Display(this string s) { Console.WriteLine(s); } // int型の拡張メソッド public static void Display(this int n) { Console.WriteLine(n.ToString()); } } class Program { static void Main(string[] args) { string s = "文字列"; s.Display(); // int型の拡張メソッドテスト int n = 99; n.Display(); } }
プログラムのメイン処理はすっきりした感じがあります。
「拡張メソッド」で気を付けたいこと
「拡張メソッド」は、あたかも元のクラスに実装されていたたメソッドのように見えてしまうので、「拡張メソッド」を使ったプログラムの「実装部分(サンプルではMain関数内の実装)だけ」を、まったく別のプログラムに持っていくとビルドエラーになってしまいます(拡張メソッド部分の実装が全くないからです)。
今回のサンプルでは、コード量が極端に少ないので拡張メソッドということがすぐわかりますが、大きなプロジェクトのプログラムなどになるとこの拡張メソッドがどこに実装されているかを見つけるのに悩んでしまいます。
(元のクラスがマイナーなクラスだとほんとにメソッドがあるように勘違いしてしまいます)
しかもその拡張メソッドを実装したクラスが、ほかのクラスやライブラリに依存していたりすると、大きな混乱を招いてしまいます。
ですので、「拡張メソッド」を作って使うときは、よくよくご検討ください。