拡張メソッドとは?
拡張メソッド(Extension Method)とは、既存のクラス、構造体を直接変更することなく、
機能を追加できる方法です。
主にC#などのプログラミング言語でサポートされています。
拡張メソッドを使用すると、ライブラリやフレームワークに含まれる、
直接ソースコードを変更できないクラスであってもそのクラスに新しい機能を追加したかのように利用できます。
実際に追加されるわけではないですが、そのクラスの一部のように動作させることが出来ます。
例えば
Unityでよく使うクラスや構造体といえば、
GameObjectMonoBehaviourTransformRectTransformVector2Vector3
などがありますよね。
ソースコードを変更できない既存のクラスに機能を追加する場合、
クラスを継承し継承先でプロパティやメソッドを追加します。
GameObjectのように、sealed 修飾子があり継承できないクラスもあります。
この場合にも拡張メソッドを使用することで機能を追加することが出来ます。
拡張メソッドの実装時の記述方法
既存のクラスに拡張メソッドを追加するには、
staticなクラスを定義し、staticなメソッドを追加、その第1引数にthis修飾子を使用して、
拡張対象のクラスやインスタンスを引数として受けとれるようにします。
これによりインスタンスメソッドのように呼び出せるようになります。
GameObjectの拡張の例
GameObjectにShow(),Hide()メソッドを追加して、
表示非表示を切り替えられるようにしてみます。
クラス名は何でもいいのですが、GameObjectを拡張するということでGameObjectExtensionとしています。
using UnityEngine;
public static class GameObjectExtension
{
public static void Show(this GameObject go)
{
go.SetActive(true);
}
public static void Hide(this GameObject go)
{
go.SetActive(false);
}
}
このようになりました。
これで以下の様に、HideメソッドをGameObjectに元からあるメソッドのように呼び出すことが出来ます。
using UnityEngine;
public class ExtensionTest : MonoBehaviour
{
private void Start()
{
gameObject.Hide();
}
}
気をつける点
クラスに拡張メソッドを追加できるのは便利ですが、いくつか気をつけるべき点もあります。
名前が衝突するリスク
拡張メソッドの名前が既存のメソッドや他の拡張メソッドと競合する場合、どのメソッドが呼ばれるのか曖昧になります。
拡張メソッドよりもインスタンスメソッドが優先させることを覚えておきましょう。
後は名前空間(namespace)を分け、明確に管理する必要があるかもしれません。
動的な多様性はサポートされない
拡張メソッドは静的なメソッドとして実装されるため、オーバーライドや仮想メソッド(virtual)には対応できません。
多様性が必要な場合は、通常の継承やインターフェイスを使用しましょう。
まとめ
今回は拡張メソッドについて説明しました。
拡張メソッドを使用することで、ソースコードを変更できないクラスであっても、後から機能を追加することができます。
例えば、GameObjectを例に挙げましたが、Transformやstringといった他のクラスや構造体でも同様に拡張が可能です。
拡張メソッドを適切に利用すれば、ソースコードの可読性や再利用性を高め、直感的で分かりやすいコード設計が実現できます。
また、よく使う処理を拡張メソッドとしてまとめることで、開発の効率を大きく向上させることも可能です。
ただし、名前の衝突や過剰な使用には注意が必要です。
設計の意図を明確にしながら、プロジェクトの一貫性を保つよう心がけてください。
ぜひ、自分のプロジェクトに合った拡張メソッドを設計してみてください!