こんにちはsuzukiです。本日はC#のマルチキャストデリゲートについてふれていこうと思います。
unityでC#のコードを触っていた際に出会ったのですが、何をしているのかわからなかったため、こちらに備忘として書いておきます。使い方は選ぶかもしれませんがきちんと設計できれば便利なのかもしれません。
C#のデリゲートについて、基本的な考え方はSwiftと同じです。処理の移譲を行うという理解で問題なさそうです。
よくわからないというかたはメソッドを変数として同じように扱う仕組みとでも理解していただければと思います。
それではデリゲートの定義の仕方です。修飾子 delegate 戻り値の型 デリゲート名 引数
//HogeDelegateという名前で戻り値はVoid 引数は(int)で作成 delegate void HogeDelegate(int a);
デリゲートの定義と同じ戻り値と引数であればデリゲートにメソッドを代入することができます。
今回の場合だと引数にintを一つ、戻り値は何も返さない。という条件に合致する必要があります。
代入とデリゲートからメソッドを呼び出すには下記のように記述します。
//HogeDelegateという名前で戻り値はvoid 引数は(int)で作成 delegate void HogeDelegate(int a); public class TestScript : MonoBehaviour { void Start() { //HogeDelegateにHoge1関数を代入 HogeDelegate hoge = Hoge1; //デリゲートから関数を呼び出し hoge(33); } // 変数名は別に違っていても問題なし。引数と戻り値が同じことが大事 static void Hoge1(int test) { Debug.Log(test); } }
引数と戻り値が同じであればクラスメソッドもインスタンスメソッドも代入可能です。
さて本題のマルチキャストデリゲートについてです。先ほどメソッドの代入は一回だけ行っておりましたが、デリゲートにメソッドの代入を複数行うことができます。メソッドが複数代入されているデリゲートをマルチキャストデリゲートと呼びます。
デリゲートに複数のメソッドを代入する場合は+=を使って代入を行います。
またデリゲートの呼び出しは代入された順に行われ、並列実行は行われません。
先ほどのコードをもとに複数のメソッドを代入しました。
//HogeDelegateという名前で戻り値はVoid 引数は(int)で作成 delegate void HogeDelegate(int a); public class TestScript : MonoBehaviour { void Start() { HogeDelegate hoge = HogeDelegate(Hoge1); hoge += Hoge2; hoge += Hoge3; hoge(11); } // 変数名は別に違っていても問題なし。引数と戻り値が同じことが大事 static void Hoge1(int a) { Debug.Log(a * 2); } static void Hoge2(int a) { Debug.Log(a * 3); } static void Hoge3(int a) { Debug.Log(a * 4); } }
実行結果
22 33 44
デリゲートに複数のメソッドを代入する場合は-=を使って削除を行います。
その際に代入しているメソッドを指定する必要があります。
二つ同じメソッドが代入されている場合は後ろから削除されていきます。
//HogeDelegateという名前で戻り値はVoid 引数は(int)で作成 delegate void HogeDelegate(int a); public class TestScript : MonoBehaviour { void Start() { HogeDelegate hoge = HogeDelegate(Hoge1); hoge += Hoge2; hoge += Hoge3; hoge += Hoge1; hoge(1);//Hoge1 Hoge2 Hoge3 Hoge1 を実行 //Hogeを削除 hoge -= Hoge1; hoge(11);//Hoge1 Hoge2 Hoge3を実行 } // 変数名は別に違っていても問題なし。引数と戻り値が同じことが大事 static void Hoge1(int a) { Debug.Log(a * 2); } static void Hoge2(int a) { Debug.Log(a * 3); } static void Hoge3(int a) { Debug.Log(a * 4); } }
実行結果
2 3 4 2 22 33 44
一応補足としてマルチキャストデリゲートの戻り値は最後に設定されたメソッドの戻り値が受け取れるみたいです。
なので基本的には戻り値を使うようなデリゲートでマルチキャストデリゲートを使うことはなさそうです。
慣れれば便利に使えるかもしれないので、引き続き学習して行きます。