C#14新機能

C#14 新機能 B02_拡張メソッドとは

B02 拡張メソッドとは

この章では、拡張メソッドについて解説します。拡張メソッドとは、変更できない型に対して、あたかもその型に元からメソッドが備わっているかのように、後から独自のメソッドを追加できる仕組みです。

図1 「拡張メソッド」タイトルスライド

プロジェクトの作成

Visual Studioを起動し、「新しいプロジェクトの作成」を選びます。プロジェクトの種類は「Windowsフォームアプリ」を選択します。

図2 Windowsフォームアプリを選択

プロジェクト名と保存場所は任意のものを指定し、対象フレームワークは.NET 10を選んでプロジェクトを作成します。

図3 プロジェクト名と保存場所の指定

変更できない型にはメソッドを追加できない

例えばintは組み込みの型なので、私たちプログラマーがint型そのものの中身を書き換えることはできません。試しにint型の変数aを宣言し、a.と入力してみると、標準で用意されているメソッドしか候補に出てきません。

図4 int型の変数aを宣言

図5 a. と入力してもint標準のメソッドしか出てこない(CompareTo、ToString、Equalsなど)

拡張メソッドを使うと、このintに対して独自のメソッドを追加し、a.の候補に表示させることができます。

拡張メソッドの作り方(1)静的クラスと静的メソッドを用意する

拡張メソッドを作るには、まずpublic staticな静的クラスを用意します。クラス名は自由ですが、ここではintを拡張する意味でIntExという名前にします。

図6 public static class IntEx を定義

値が0のときにtrueを返すIsZeroというメソッドを作ってみます。まずは拡張メソッドにする前の、普通の静的メソッドとして書きます。

public static class IntEx
{
  public static bool IsZero(int value)
  {
    return value == 0;
  }
}

 

図7 IsZeroメソッドを普通の静的メソッドとして実装

この時点ではIsZeroはaが持っているメソッドではなく、あくまでIntExクラスが持っている静的メソッドです。そのため、次のようにIntEx.IsZero(a)という形でしか呼び出せません。

int a = 1;
bool ret1 = IntEx.IsZero(a);

 

図8 IntEx.IsZero(a) という形で静的メソッドとして呼び出す

拡張メソッドの作り方(2)第一引数にthisを付ける

ここでIsZeroメソッドの第一引数にthisキーワードを付けます。「このメソッドは第一引数のint型のメソッドにしてね」という意味になり、これが拡張メソッドの宣言になります。

public static class IntEx
{
  public static bool IsZero(this int value)
  {
    return value == 0;
  }
}

 

図9 第一引数に this を付けて拡張メソッドにする

thisを付けたことで、int型の変数aに対してa.と入力すると、候補に「(拡張) bool IsZero()」としてIsZeroが表示されるようになります。intの中身自体を変えたわけではなく、あくまで自分で後付けでメソッドを追加した形になります。

図10 a. の候補に拡張メソッドIsZeroが表示される

これで、a.IsZero()という形で、あたかもint型が最初からIsZeroメソッドを持っているかのように呼び出せるようになります。

int a = 1;
bool ret1 = a.IsZero();

int b = 0;
bool ret2 = b.IsZero();

 

実行して確認すると、a は 1 なので ret1 は false、b は 0 なので ret2 は true となり、意図した通りにIsZeroが動作していることが分かります。

図11 ret1にブレークポイントを設定してデバッグ実行

引数を増やす場合

拡張メソッドも通常のメソッドと同様に、第二引数以降を増やすことができます。例えば文字列を受け取りたい場合は、次のように書けば、その値を使ってロジックを組むことができます。

public static bool IsZero(this int value, string valueA)
{
  return value == 0;
}

 

this が付くのは常に第一引数だけで、そこにインスタンスの値(a.IsZero()と呼び出したときのa自身の値)が渡されます。第二引数以降は呼び出し側で自由に指定できる、通常の引数として扱われます。

まとめ

拡張メソッドは、①public staticな静的クラスを作り、②その中にpublic staticなメソッドを作り、③第一引数にthisを付ける、という3ステップで作成できます。int型に限らず、変更できないあらゆる型に対して、自分専用のメソッドを後付けで追加できるのが拡張メソッドの特徴です。

C#14 新機能