この章のテーマ §
拡張メソッドについて学びます。拡張メソッドの作成方法と利用方法法を説明します。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, string型, クラスの基礎, メソッドの基礎, thisキーワード, usingディレクティブ
解説 §
拡張メソッドは型にメソッドを後から追加する方法です。サンプルソースは、本来拡張できないはずのstring型に、文字列をオレ語に変換するToOregoメソッドを追加した例です。オレ語は、全ての「オ」を「レレ」に置き換えた言葉とします。
拡張メソッドを定義するには、適当な静的なクラスの中でpublic static string ToOrego(this string str)のように静的なメソッドを書きます。ただし、引数にはthisキーワードを付けておきます。これで、引数の型であるstring型のメソッドが増えたかのように扱えます。
利用する場合は、呼び出し側と拡張メソッドが含まれる名前空間が一致しない場合、usingディレクティブが必須です。その点だけ注意すれば、あとはもともと型に存在するメソッドと同じように呼び出せます。
罠の数々 §
- 拡張メソッドで、既存のメソッドを置き換えることはできない
- sealedキーワードが付いていてそれ以上継承できないクラス(例:string)にもメソッドを追加できるが、既存のメソッドを置き換えることはできない。増やすだけである
- 拡張メソッドはしばしば【拡張子】と表記されるがこれは誤訳である。extension methodは拡張メソッドと訳されているが、ファイルの拡張子はfile extensionである。その結果、なぜかextensionというと条件反射的に拡張子と訳してしまう翻訳者ないし機械翻訳が存在するようだが、当然公式の訳語ではなく誤訳である (しかし、何回指摘してもなくならない)
参考リンク §
拡張メソッド (C# プログラミング ガイド)
サンプルソース: extensionMethods §
string s = "オレのおじさん";
Console.WriteLine($"変換前: {s}");
Console.WriteLine($"変換後: {s.ToOrego()}");
public static class MyExtensions
{
public static string ToOrego(this string str)
{
return str.Replace("オ", "レレ");
}
}
実行結果 §
変換前: オレのおじさん
変換後: レレレのおじさん
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
usingディレクティブ抜きには拡張メソッドは呼び出せないはずなのに、LINQの拡張メソッド(System.Linq.Whereメソッド)は呼び出せ、以下のプログラムは実行できてしまう。なぜだろうか。
int[] ar = { 1, 2, 3 };
foreach (var item in ar.Where(x => x == 1)) Console.WriteLine(item);
- LINQは例外的にusingディレクティブ抜きに使用できる
- スクロールアップすると上の方にusing System.Linq;と書いてある
- SDKの共通定義のファイルにusing System.Linq;と書いてある
- 馬鹿には見えないインクでusing System.Linq;と書いてある
- ソースコードに領域を設定して不可視にできる#regionディレクティブで、不可視状態になっている
[[解答]]