このレクチャーでは、拡張メソッドを整理するための「extensionブロック」について解説します。extensionブロックを使うと、同じ型を拡張する複数のメンバーをグルーピングできるだけでなく、メソッド以外にプロパティなども書けるようになります。
これまでの拡張メソッドの書き方
まずはグルーピングの考え方から見ていきます。次のように、int型を拡張してゼロかどうかを判定するIsZeroという拡張メソッドがあったとします。
図1: 既存のIsZero拡張メソッド(IntEx.IsZero(a) を a.IsZero() に書き換え済みの状態)
public static class IntEx
{
public static bool IsZero(this int value)
{
return value == 0;
}
}
ここにマイナス値かどうかを判定するIsNegativeを追加しようとすると、これまでは同じようにthisキーワードを使ったstaticメソッドとして、もう一つ書き足していくことになります。
図2: 従来の書き方でIsNegativeを追加した状態(IsZeroとは別に、同じ形のstaticメソッドを書き足している)
public static class IntEx
{
public static bool IsZero(this int value)
{
return value == 0;
}
public static bool IsNegative(this int value)
{
return value < 0;
}
}
このように、拡張したい機能が増えるたびに、同じ形のstaticメソッドをバラバラに書き足していくことになります。
extensionブロックで書き直す
extensionブロックを使うと、この書き方を整理できます。extensionと書いて、括弧の中に拡張したい型と変数名を指定します。これは、これまで拡張メソッドの第一引数に書いていたthis int valueと同じ内容ですが、thisは付けません。
図3: extension(int value) ブロックを追加し、IsZeroの引数(this int value)を削除しようとしている状態
public static class IntEx
{
extension(int value)
{
}
public static bool IsZero(this int value)
{
return value == 0;
}
}
このブロックでIsZeroとIsNegativeを囲むと、まずstaticが不要になります。また、ブロックの引数として宣言したvalueがそのまま使えるので、メソッド自身の引数(this int value)も不要になります。extensionブロックの中身は、この型(今回はint)の拡張になっているので、メソッドを書けばメソッドの拡張に、プロパティを書けばプロパティの拡張になります。
図4: staticとthis int valueを削除し、extensionブロックの引数valueを使う形に書き換えた状態
public static class IntEx
{
extension(int value)
{
public bool IsZero()
{
return value == 0;
}
public bool IsNegative()
{
return value < 0;
}
}
}
これまではthis intとバラバラに書いていたものが、extension(int value)というひとつのブロックの中にまとまり、int型を拡張したいメンバーをここに集めて書いておけるようになります。つまりグルーピングができるということです。
図5: IsZeroとIsNegativeの両方がextension(int value)ブロックの中にグルーピングされている状態
呼び出し側のコードは変わらない
extensionブロックを使って書き換えても、呼び出す側のクライアントコードは一切変更する必要がありません。これまでと全く同じ書き方のまま利用できます。
int a = 1; bool ret1 = a.IsZero(); int b = 0; bool ret2 = b.IsZero();
実際に実行して確認すると、ret1がfalse、ret2がtrueとなり、正しく動作していることが分かります。
図6: デバッグ実行でret1にfalseが代入されていることを確認
もちろんIsNegativeについても、これまでと同様に使うことができます。マイナス値を代入したaに対してIsNegativeを呼び出すと、trueが返ってきます。
int a = -1; bool ret1 = a.IsNegative(); int b = 0; bool ret2 = b.IsNegative();
図7: マイナス値を代入したaに対してIsNegative()を呼び出している状態
マイナス1を入れたaのIsNegativeはtrueが返り、0を入れたbのIsNegativeはfalseが返ります。
まとめ
extensionと書いて拡張したい型を指定し、そのブロックの中に普通のクラスと同じ感覚でメソッド(やプロパティ)を書くことで、対象の型を拡張するメンバーをグルーピングして整理できます。ブロックの引数として宣言した変数を、ブロック内の各メンバーでそのまま使って処理を書くことができます。
Udemyでの動画版はこちらからご覧いただけます
00_はじめに
01_VisualStudio2026をインストールしてください
A01_fieldキーワード
B01_extensionブロックとは
B02_拡張メソッドとは
B03_extensionブロック
B04_型パラメータありの拡張メソッド
B05_型パラメータありのextensionブロックの書き方
B06_拡張プロパティ
B07_拡張静的プロパティ&メソッド
B08_拡張演算子
C01_partialコンストラクター
C02_幽霊コードを定義パーツで契約による実装をするという考え方
C03_partialイベント
D01_Null条件付き代入
E01_複合代入演算子のオーバーロード
F01_明示的な型を指定せずにラムダパラメータでパラメータ修飾子を使用する
G01_nameofはバインドされていないジェネリック型をサポートします
H01_SpanTおよびReadOnlySpanTのより暗黙的な変換
Udemyでの動画版はこちらからご覧いただけます