書籍転載
|
本コーナーは、日経BPソフトプレス発行の書籍『文法からはじめる プログラミング言語Microsoft Visual C#入門』の中から、特にInsider.NET読者に有用だと考えられる章や個所をInsider.NET編集部が選び、同社の許可を得て転載したものです。基本的に元の文章をそのまま転載していますが、レイアウト上の理由などで文章の記述を変更している部分(例:「上の図」など)や、図の位置などを本サイトのデザインに合わせている部分が若干ありますので、ご了承ください。『文法からはじめる プログラミング言語Microsoft Visual C#入門』の詳細は「目次情報ページ」もしくは日経BPソフトプレスのサイトをご覧ください。 |
ご注意:本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。 |
■11.5 拡張メソッド(C#バージョン 3.0以降)
拡張メソッドとは、既にあるクラスを継承せずにメソッドを追加するものです。派生クラスとして機能を追加するのではなく、あたかも最初からそのメソッドが存在していたかのように、元のクラスのメソッドとして呼び出すことができるのです。
この機能が強力なのは、ユーザー定義のクラスだけでなく、.NET Frameworkであらかじめ定義されているクラスに対しても機能が追加できるという点です。さらに、継承できないシールクラス(sealedアクセス修飾子が指定されたクラス)にもメソッドを定義できます。ただし、拡張メソッドはクラスの外部から機能を拡張するものなので、元のクラスのprivateメンバにはアクセスできません。
図11-4 拡張メソッド |
拡張メソッドは、独立した静的クラスの静的メソッドとして定義する必要があります。また、追加するメソッドの最初のパラメータには、thisキーワードで拡張するクラスを指定します。
|
|
[構文]拡張メソッドの定義 |
●11.5.1 ユーザー定義のクラスを拡張する
まず、ユーザー定義のクラスを拡張してみます。なお、この章の以降のサンプルコードでは、System.Core.dllというアセンブリへの参照設定が必要になります(参照設定については11.5.4項で説明します)。それには、ソリューションエクスプローラで[参照設定]をクリックして[プロジェクト]メニューの[参照の追加]をクリックします。図11-5の[参照の追加]ダイアログボックスが表示されるので、一覧から[System.Core]をクリックして[OK]をクリックすると、ソリューションエクスプローラに[System.Core]が追加されます。
図11-5 [参照の追加]ダイアログボックス |
次のサンプルコードでは、TestClassを拡張するために、ExtendTestClassクラスで拡張メソッドcheckJを定義しています。
|
|
[サンプル]extend1.cs |
TestClassクラスでは、体重と身長を保持するプロパティを定義しています。身長の場合、初期値をセンチメートル単位と見なして、100で割ったメートル単位の値を取得できるようにしています。BMIメソッドは、肥満度を示すBMI値を返します。
拡張メソッドcheckJでは、BMI値を利用して肥満度の判定を行い、結果を表示します。あたかもTestClassのメソッドであるかのように、a.checkJ()という形で呼び出しています。
●11.5.2 .NET Frameworkのクラスを拡張する
今度は、.NET Frameworkで定義されているSystem.Stringクラスを拡張してみましょう。次のサンプルコードでは、拡張メソッドとして16進数の文字列を数値に変換する処理を定義しています。拡張メソッドのパラメータには、System.Stringのエイリアスであるstringを指定しています。なお、元のクラスに同じ名前のメソッドがあった場合はエラーにはならず、単に拡張メソッドが無視されます。
|
|
[サンプル]extend2.cs |
●11.5.3 拡張メソッドと名前空間
先ほどのサンプルコードでは名前空間を定義していないため、拡張メソッドも拡張されるクラスも、既定の同一の名前空間にあることになります。
拡張されるクラスと異なる名前空間で拡張メソッドを定義している場合は、次のようにusingディレクティブで使用したい拡張メソッドが含まれる名前空間の使用を宣言します。拡張メソッドは通常のメソッドのように完全修飾名で指定できないため、どの名前空間の拡張メソッドを使用するかを指定するためには、必ずusingディレクティブが必要です。
先ほどの「extend2.cs」を書き換えて、拡張メソッドを別の名前空間に定義した場合のサンプルコードを示します。
|
|
[サンプル]extend3.cs |
拡張メソッドは名前空間Xで定義されているため、「using X;」の宣言を削除すると、拡張メソッドが見つからずエラーになります。
当然ながら、同じ名前空間に同じ名前の拡張メソッドを定義すると、どの拡張メソッドを呼び出すのか特定できないためエラーになります。また、同じ名前の拡張メソッドを含む複数の名前空間の使用を宣言すると、同じ理由によりエラーになります。
●11.5.4 参照設定とアセンブリ
参照設定とは、.NET Frameworkや他のプロジェクトで作成されたクラスライブラリを使う場合に、そのライブラリが含まれるアセンブリを指定するものです。.NET Frameworkの基本的なライブラリについては、特に指定しなくても参照するようになっているため、これまでのサンプルコードでは追加の参照設定は不要でした。また、プロジェクトのテンプレートで「空のプロジェクト」ではなく「コンソールアプリケーション」などを選んだ場合、テンプレートに.NET Frameworkの参照設定の追加が含まれているため、本書のサンプルコードの範囲では参照設定の追加は不要です。「空のプロジェクト」の場合は何も設定されませんので、プログラムに応じて自分で設定する必要があります。
なお、.NET Frameworkにおけるアセンブリとは、アプリケーションなどを管理する単位となるコンパイル済みのコード群のことです。実行ファイルであるexeファイルやdllファイルと同じ形式ですが、その中にバージョンやセキュリティに関する情報も含まれています。それらの付加情報を利用することで、アセンブリのバージョンの違いによって生じる不具合を回避することができます。
【コラム】System.Linq名前空間 |
新規プロジェクトの作成時に各種のテンプレートを使うと、既定でいくつかのusingディレクティブが追加されます。その中の1つであるSystem.Linqは、LINQという機能を使うために必要な名前空間です。System.Linq名前空間にはLINQ特有の機能に加え、コレクションクラス(System.Collections.IEnumerableなど)にクエリ機能を追加するための拡張メソッドの定義が含まれています。それらの拡張メソッドを利用するためには、usingディレクティブでSystem.Linqの使用を宣言する必要があります。 |
■
『文法からはじめる プログラミング言語Microsoft Visual C#入門』の転載は今回のみです。このほかのコンテンツについては、「目次情報ページ」もしくは日経BPソフトプレスのサイトをご覧ください。
「文法からはじめる プログラミング言語Microsoft Visual C#入門」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|