delegateを自ら使う機会はほとんどないのですが、ライブラリのソースコードを読む時にたまに遭遇して、そこで「うっ」となったりします。
このままだとよくないので、delegateを脳に染み込ませるためにも、改めてサンプルコードを書いてみました。
あくまで、個人用のメモであり、delegateとは何なのか?いつ使うのか?等の話は出てきません。ご了承ください。
サンプルコード
Unityで使えるサンプルコードを書いてみました。(delegateはUnity以外でも利用できます。)
using UnityEngine;
namespace Practice
{
// デリゲートを宣言します
public delegate void Printer(string s);
/// <summary>
/// 任意のGameObjectにアタッチしてご利用ください。
/// </summary>
public class DelegatePractice : MonoBehaviour
{
private void Start()
{
// newでデリゲートを生成できます。
var printA = new Printer(Debug.Log);
// 実行すると、「Hello World A」とコンソールに表示されます。
printA("Hello World A");
// newを省略することができます。この場合、varは利用できません。
Printer printB = Debug.Log;
// 実行すると、「Hello World B」と表示されます。
printB("Hello World B");
// 匿名メソッドでデリゲートを生成できます。
Printer printC = delegate(string s) { Debug.Log(s); };
// 「Hello World C」と表示されます。
printC("Hello World C");
// ラムダ式でデリゲートを生成できます。JavaScript経験者なら馴染みのある書き方だと思います。
Printer printD = (string s) => { Debug.Log(s); };
// 「Hello World D」と表示されます。
printD("Hello World D");
// 複数のデリゲートを生成し、+で結合できます。
var printE = new Printer(Debug.Log) + new Printer(Debug.Log);
// この場合、「Hello World E」が2回表示されます。
printE("Hello World E");
// 登録したものを-で削除できます。以下では、「Debug.Log」を2回登録してから、1回削除しています。
var printF = new Printer(Debug.Log) + new Printer(Debug.Log) - new Printer(Debug.Log);
// この場合、「Hello World F」が1回表示されます。
printF("Hello World F");
// +=で後から追加したり、-=で後から削除したりできます。以下では、「Debug.Log」を2回登録してから、1回削除しています。
var printG = new Printer(Debug.Log);
printG += new Printer(Debug.Log);
printG -= new Printer(Debug.Log);
// この場合、「Hello World G」が1回表示されます。
printG("Hello World G");
}
}
}
こんな風に、1つの変数に複数のデリゲートを登録したり削除したりできます。
delegateという英単語のニュアンス
delegate という英単語を辞書で調べると「委任」という意味が出てきます。
この委任という言葉がいまいちピンと来ないんですが、あえて委任という言葉を使って、上記のサンプルコードを説明する場合、
「DelegatePractice
というクラスが、 Printer
という処理を、 Debug
というクラスに委任している。」
ということになると思います。(間違っていたらすみません。)
さいごに
本記事作成にあたり、以下の記事を参考にさせていただきました。わかりやすい記事、ありがとうございました。