C#の拡張メソッドについて勉強してみる

はいどーもこんにちは風邪が治らないニート(希望はプログラマ)です。
本日は「拡張メソッド」について勉強していきたいと思います。

拡張メソッドとはなんぞ

拡張メソッドの概要についてはC#プログラミングガイドを参照しましょう。
C#プログラミングガイドの説明によれば、「新規の派生型の作成、再コンパイル、または元の型の変更を行うことなく既存の型にメソッドを “追加”」できる機能のようです。
しかし「拡張された型のインスタンスメソッドのように呼び出し」ているだけであり、実態は「静的メソッド」です。
なんでもLINQと相性がよいらしいですよ。

拡張メソッドを実装してみる

「カスタム拡張メソッドを実装して呼び出す」を参考にして拡張メソッドを実装してみます。

1.拡張メソッドを格納するための静的クラスを定義
2.拡張メソッドを静的メソッドとして実装

まずはここまでやってみます。

ご覧の通り、StringExtensionクラスにはstatic修飾子が付加されています
拡張メソッドはstaticクラスの中に定義しなければならないという制約があるため、これは必須です。

次にWordCountメソッドを定義しています。
拡張メソッドの実態は静的メソッドなので、static修飾子を付加しています。

さてここで第一引数に注目してください。
「this」修飾子が付加されているのがわかるかなと思います。
これは拡張メソッドを作る際の約束事のようですね。

「this」修飾子のあとには、拡張したい型を指定します。
今回ならString型ですね。
ここでは第一引数までしか指定していませんが、もし拡張メソッドを呼び出す際に引数を渡したい場合、第二引数以降に宣言するようです。

拡張メソッドという聞きなれない用語に身構えていましたが、意外と簡単に実装できちゃいました。

拡張メソッドを呼び出してみる

さて拡張メソッドの実装は終わりました。
次は実際に呼び出してみましょう。

「カスタム拡張メソッドを実装して呼び出す」によれば、「呼び出し元のコードで、using ディレクティブを追加して、拡張メソッドのクラスを含む名前空間を指定」するらしいのですが、僕は同じ名前空間に拡張メソッドを定義したので(例のごとくコンソールアプリ)、これは省略します。
というわけで、Mainメソッド内で「型のインスタンス メソッドと同じようにメソッドを呼び出し」てみましょう。

今回拡張したのはString型です。
というわけでstring型に対してWordCountメソッドを実行しています。
このとき、WordCountメソッドに第一引数を指定する必要はありません。
なぜなら、第一引数は「演算子を適用する型を表すものであり、コンパイラはオブジェクトの型を既に認識している」からです。

また、ご覧の通り、通常の静的メソッドとしてWordCountメソッドを呼び出すことも可能です。
当然ながらこのときには第一引数を指定してやる必要があります。

実行結果はこんな感じ。

拡張メソッドを用いる際の注意点

「一般的なガイドライン」を参照すればわかる通り、「必要な場合に限り注意して実装する」ことが勧められています。
また、「名前の衝突の解決では、型自体で定義されているインスタンス メソッドまたは静的メソッドが常に優先されるため、型の既存のメソッドを偽装するために拡張メソッドが使用されることはありません」とのことです。
便利だからと言って、闇雲に拡張メソッドを追加しまくらないようにしましょう。
その他の注意点も含め、こちらのサイトがわかりやすく説明してくれているかなと思います。

おわりに

実は匿名メソッドの外部変数についても書こうとしていたのですが、一つにまとめるとかなり長くなりそうだったので今回は拡張メソッドについてのみ書きました。
パッと見た感じ、外部変数って要はJavaScriptのクロージャと同じですかね。
JavaScriptの知識が生きていますねえ。
そろそろLINQについてもちゃんと勉強して記事にしたいなあ。

ほなそんな感じでまた。

フォローする